无法访问已关闭的流?
Cannot access a closed Stream?
我刚刚在打开文件并读取原始数据的代码中遇到错误。
我得到的错误如下:
如您所见,我正在打开一个内存流,但在这样做时我收到一条错误消息,提示我无法访问该流?
为什么我无法访问已关闭的流?
使用的代码:
// Try to decompress the file data.
byte[] rawData = null;
using (MemoryStream zipStream = new MemoryStream(fileData))
{
if (ZipPackage.IsZipFile(zipStream))
{
using (ZipPackage unzipper = ZipPackage.Open(zipStream))
{
// The zip package only contains one entry since GeoObject.FileData only contains one shape or POI.
if (unzipper.ZipPackageEntries.Count > 0)
{
StreamReader reader = new StreamReader(unzipper.ZipPackageEntries[0].OpenInputStream());
rawData = System.Text.Encoding.UTF8.GetBytes(reader.ReadToEnd());
}
}
}
}
堆栈
at System.IO.__Error.StreamIsClosed()
at System.IO.MemoryStream.set_Position(Int64 value)
at Telerik.Windows.Zip.ZipPackage.IsZipFile(Stream stream)
at Satmap.Planner.Silverlight.XmlConverters.DBGeoObjectsToFromDBShapes.ExtractRawFileData(GeoObject geoObject, Byte[] fileData)
at Satmap.Planner.Silverlight.DatabaseShapesToFromMapShapes.ConvertDatabaseShapesToMapShapes(GeoObject geoObject, Boolean filter)
at Satmap.Planner.Silverlight.DatabaseShapesToFromMapShapes.ConvertDatabaseShapesToMapShapes(GeoObject geoObject)
at Satmap.Planner.Silverlight.ViewControllers.MainMapViewController.BackgroundWorkerFileLoad_RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e)
at System.ComponentModel.BackgroundWorker.OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
at System.ComponentModel.BackgroundWorker.<OnRun>b__1(Object state)
新堆栈:
at System.IO.MemoryStream.set_Capacity(Int32 value)
at System.IO.MemoryStream.EnsureCapacity(Int32 value)
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize)
at System.IO.Stream.CopyTo(Stream destination)
at Telerik.Windows.Zip.ZipArchive.WriteArchive()
at Telerik.Windows.Zip.ZipArchive.Dispose(Boolean disposing)
at Telerik.Windows.Zip.ZipArchive.Dispose()
at Satmap.Planner.Silverlight.XmlConverters.DBGeoObjectsToFromDBShapes.ExtractRawFileData(GeoObject geoObject, Byte[] fileData)
at Satmap.Planner.Silverlight.DatabaseShapesToFromMapShapes.ConvertDatabaseShapesToMapShapes(GeoObject geoObject, Boolean filter)
at Satmap.Planner.Silverlight.DatabaseShapesToFromMapShapes.ConvertDatabaseShapesToMapShapes(GeoObject geoObject)
at Satmap.Planner.Silverlight.ViewControllers.MainMapViewController.BackgroundWorkerFileLoad_RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e)
at System.ComponentModel.BackgroundWorker.OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
at System.ComponentModel.BackgroundWorker.<OnRun>b__1(Object state)
您在这里看到的是 Telerik ZipPackage
class 的行为。静态 IsZipFile
方法正在处理流,可能是由于错误(您可以就此联系 Telerik 支持)。
但是,您可能没有必要首先检查 zip 包的有效性。只需在相关代码段周围使用 try...catch
:
// Try to decompress the file data.
byte[] rawData = null;
using (MemoryStream zipStream = new MemoryStream(fileData))
{
try
{
using (ZipPackage unzipper = ZipPackage.Open(zipStream))
{
// The zip package only contains one entry since GeoObject.FileData only contains one shape or POI.
if (unzipper.ZipPackageEntries.Count > 0)
{
StreamReader reader = new StreamReader(unzipper.ZipPackageEntries[0].OpenInputStream());
rawData = System.Text.Encoding.UTF8.GetBytes(reader.ReadToEnd());
}
}
}
catch (Exception ex)
{
// ZipPackage throws an exception of type Exception if the
// package is not valid. Handle exception here, e.g. log etc
}
}
更新
Telerik 的 ZipArchive class 似乎是一个奇怪的野兽。如果您使用的是 .NET 4.5 或更高版本,最好切换到 System.IO.Compression.ZipArchive
class。如果不是,您可以通过不从固定数组创建内存流来解决不可扩展内存流的问题。您可以使用:
而不是 new MemoryStream(fileData)
using (var zipStream = new MemoryStream())
{
zipStream.Write(fileData, 0, fileData.Length);
zipStream.Position = 0;
// continue here
}
我刚刚在打开文件并读取原始数据的代码中遇到错误。
我得到的错误如下:
为什么我无法访问已关闭的流?
使用的代码:
// Try to decompress the file data.
byte[] rawData = null;
using (MemoryStream zipStream = new MemoryStream(fileData))
{
if (ZipPackage.IsZipFile(zipStream))
{
using (ZipPackage unzipper = ZipPackage.Open(zipStream))
{
// The zip package only contains one entry since GeoObject.FileData only contains one shape or POI.
if (unzipper.ZipPackageEntries.Count > 0)
{
StreamReader reader = new StreamReader(unzipper.ZipPackageEntries[0].OpenInputStream());
rawData = System.Text.Encoding.UTF8.GetBytes(reader.ReadToEnd());
}
}
}
}
堆栈
at System.IO.__Error.StreamIsClosed()
at System.IO.MemoryStream.set_Position(Int64 value)
at Telerik.Windows.Zip.ZipPackage.IsZipFile(Stream stream)
at Satmap.Planner.Silverlight.XmlConverters.DBGeoObjectsToFromDBShapes.ExtractRawFileData(GeoObject geoObject, Byte[] fileData)
at Satmap.Planner.Silverlight.DatabaseShapesToFromMapShapes.ConvertDatabaseShapesToMapShapes(GeoObject geoObject, Boolean filter)
at Satmap.Planner.Silverlight.DatabaseShapesToFromMapShapes.ConvertDatabaseShapesToMapShapes(GeoObject geoObject)
at Satmap.Planner.Silverlight.ViewControllers.MainMapViewController.BackgroundWorkerFileLoad_RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e)
at System.ComponentModel.BackgroundWorker.OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
at System.ComponentModel.BackgroundWorker.<OnRun>b__1(Object state)
新堆栈:
at System.IO.MemoryStream.set_Capacity(Int32 value)
at System.IO.MemoryStream.EnsureCapacity(Int32 value)
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize)
at System.IO.Stream.CopyTo(Stream destination)
at Telerik.Windows.Zip.ZipArchive.WriteArchive()
at Telerik.Windows.Zip.ZipArchive.Dispose(Boolean disposing)
at Telerik.Windows.Zip.ZipArchive.Dispose()
at Satmap.Planner.Silverlight.XmlConverters.DBGeoObjectsToFromDBShapes.ExtractRawFileData(GeoObject geoObject, Byte[] fileData)
at Satmap.Planner.Silverlight.DatabaseShapesToFromMapShapes.ConvertDatabaseShapesToMapShapes(GeoObject geoObject, Boolean filter)
at Satmap.Planner.Silverlight.DatabaseShapesToFromMapShapes.ConvertDatabaseShapesToMapShapes(GeoObject geoObject)
at Satmap.Planner.Silverlight.ViewControllers.MainMapViewController.BackgroundWorkerFileLoad_RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e)
at System.ComponentModel.BackgroundWorker.OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
at System.ComponentModel.BackgroundWorker.<OnRun>b__1(Object state)
您在这里看到的是 Telerik ZipPackage
class 的行为。静态 IsZipFile
方法正在处理流,可能是由于错误(您可以就此联系 Telerik 支持)。
但是,您可能没有必要首先检查 zip 包的有效性。只需在相关代码段周围使用 try...catch
:
// Try to decompress the file data.
byte[] rawData = null;
using (MemoryStream zipStream = new MemoryStream(fileData))
{
try
{
using (ZipPackage unzipper = ZipPackage.Open(zipStream))
{
// The zip package only contains one entry since GeoObject.FileData only contains one shape or POI.
if (unzipper.ZipPackageEntries.Count > 0)
{
StreamReader reader = new StreamReader(unzipper.ZipPackageEntries[0].OpenInputStream());
rawData = System.Text.Encoding.UTF8.GetBytes(reader.ReadToEnd());
}
}
}
catch (Exception ex)
{
// ZipPackage throws an exception of type Exception if the
// package is not valid. Handle exception here, e.g. log etc
}
}
更新
Telerik 的 ZipArchive class 似乎是一个奇怪的野兽。如果您使用的是 .NET 4.5 或更高版本,最好切换到 System.IO.Compression.ZipArchive
class。如果不是,您可以通过不从固定数组创建内存流来解决不可扩展内存流的问题。您可以使用:
new MemoryStream(fileData)
using (var zipStream = new MemoryStream())
{
zipStream.Write(fileData, 0, fileData.Length);
zipStream.Position = 0;
// continue here
}