2011-10-05 3 views
1

파일이 생성되고 크기가 괜찮은 것 같지만 두 번 클릭하면 형식이 잘못되었거나 파일이 손상되었다고 표시됩니다. dotnetzip 라이브러리를 사용하여 스트림을 압축하는 동안 손상된 파일

내가 호출 방법

SaveStreamToFile(documentCompressedName,getDocument()); 

의 getDocument (에 그런

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; 
} 

을 사용하고 코드) 압축 내부적으로

그리고 그 메소드를 호출 드디어

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); 
    } 
} 

아이디어? 미리 감사드립니다. 기예르모.

답변

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이 전혀 바이트를 읽지 않습니다. 16 진수 편집기로 출력 zip 파일을 여는 경우, 아마도 0으로 가득 찬 것을 볼 수있을 것입니다.

당신은 여기에 옵션이 있습니다,하지만 내 제안하려고하는 것입니다 :

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

관련 문제