无法访问封闭的流?

时间:2015-12-16 12:17:04

标签: c# stream streamreader memorystream

我刚刚在代码中遇到错误,该错误会打开文件并读取rawData。

我得到的错误如下:

enter image description 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)

1 个答案:

答案 0 :(得分:2)

您在此处看到的是Telerik ZipPackage课程的行为。静态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课程似乎是一个奇怪的野兽。如果您使用的是.NET 4.5或更高版本,则最好切换到System.IO.Compression.ZipArchive类。如果没有,您可以通过不从固定数组创建内存流来解决不可扩展内存流的问题。您可以使用以下new MemoryStream(fileData)代替:

using (var zipStream = new MemoryStream())
{
    zipStream.Write(fileData, 0, fileData.Length);
    zipStream.Position = 0;

    // continue here
}