2011-10-05 122 views
1

该文件已创建,大小似乎没问题,但是当我双击它说它的格式是错误的或文件已损坏。使用dotnetzip库压缩流时损坏的文件

这是我使用

public MemoryStream CompressFiles(Dictionary<string, MemoryStream> filesToBeCompressed) 
{ 
    var output = new MemoryStream(); 
    using (var zip = new ZipFile()) 
    { 
     foreach (var entry in filesToBeCompressed) 
     { 
      entry.Value.Seek(0, SeekOrigin.Begin); // <-- must do this after writing the stream (I've read this in a blog 
      zip.AddEntry(entry.Key.Substring(entry.Key.LastIndexOf('/') + 1, entry.Key.Length - entry.Key.LastIndexOf('/') - 1), entry.Value); 
      zip.Save(output); 
     } 
    } 
    return output; 
} 

然后在调用方法

SaveStreamToFile(documentCompressedName,getDocument()); 

getDocument(代码)调用压缩内部

这方法终于

private static void SaveStreamToFile(string fileFullPath, Stream stream) 
{ 
    if (stream.Length == 0) return; 

    // Create a FileStream object to write a stream to a file 
    using (FileStream fileStream = System.IO.File.Create(fileFullPath, (int)stream.Length)) 
    { 
     // Fill the bytes[] array with the stream data 
     var bytesInStream = new byte[stream.Length]; 
     stream.Read(bytesInStream, 0, (int)bytesInStream.Length); 

     // Use FileStream object to write to the specified file 
     fileStream.Write(bytesInStream, 0, bytesInStream.Length); 
    } 
} 

An你的想法? 在此先感谢!吉列尔莫。

回答

3

我认为问题出在您的功能SaveStreamToFile。在将存档写入磁盘之前,您必须将流的位置设置为开始位置:

private static void SaveStreamToFile(string fileFullPath, Stream stream) 
{ 
    if (stream.Length == 0) return; 

    // Set the position within the stream to the beginning of the stream 
    stream.Seek(0, SeekOrigin.Begin);  

    // Create a FileStream object to write a stream to a file 
    using (FileStream fileStream = System.IO.File.Create(fileFullPath, (int)stream.Length)) 
    { 
    // Fill the bytes[] array with the stream data 
    var bytesInStream = new byte[stream.Length]; 
    stream.Read(bytesInStream, 0, (int)bytesInStream.Length); 

    // Use FileStream object to write to the specified file 
    fileStream.Write(bytesInStream, 0, bytesInStream.Length); 
    } 
} 

希望这会有所帮助。

+0

谢谢!你是对的! – polonskyg

1

从你的代码片段中,我猜这里是MemoryStream的Position在流传递到SaveStreamToFile时位于流的末尾,并且由于你从未将位置设置回流的起始位置,因此你的stream.Read实际上是根本没有读取字节。如果你用十六进制编辑器打开你的输出压缩文件,你可能会看到它满了零。

你有多种选择这里,但我的建议是尝试:

private static void SaveStreamToFile(string fileFullPath, Stream stream) 
{ 
    if (stream.Length == 0) return; 

    // Create a FileStream object to write a stream to a file 
    using (FileStream fileStream = System.IO.File.Create(fileFullPath, (int)stream.Length)) 
    { 
     // Use FileStream object to write to the specified file 
     fileStream.Write(stream.GetBuffer(), 0, stream.Length); 
    } 
} 

此方法可避免服用MemoryStream的内部存储器缓冲区的副本。虽然我不知道你的zip文件有多大,所以它可能不是内存使用方面的问题,但将zip文件存储在内存中两次 - 一次在MemoryStream中,并且再次在原始bytesInStream数组中看起来没有必要。

+0

你刚刚救了我的一天。谢谢! – nrodic

相关问题