2017-01-26 20 views
0

zipファイルを指定すると、指定された圧縮レベル(たとえば圧縮なし)で再作成する必要があります。別のzipファイルからzipファイルを再作成

私はほとんどそこだけど、エラーが出ます:

Failed: Number of entries expected in End Of Central Directory does not correspond to number of entries in Central Directory.

私は窓に再作成されたzipファイルを保存した場合、それが正しいだように見える(正しいファイルサイズ、エントリのすべてが正しいファイルサイズで存在します)いずれのファイルも抽出可能ではありません。私がしなければ、関数の終わりに

public static byte[] ReCompress(byte[] originalArchive, CompressionLevel newCompressionLevel) 
{ 
    var entries = new Dictionary<string, byte[]>(); 

    /////////////////////////// 
    // STEP 1: EXTRACT ALL FILES 
    /////////////////////////// 
    using (var ms = new MemoryStream(originalArchive)) 
    using (var originalZip = new ZipArchive(ms, ZipArchiveMode.Read)) 
    { 
     foreach (var entry in originalZip.Entries) 
     { 
      var isFolder = entry.FullName.EndsWith("/"); 
      if (!isFolder) 
      { 
       using (var stream = entry.Open()) 
       using (var entryMS = new MemoryStream()) 
       { 
        stream.CopyTo(entryMS); 
        entries.Add(entry.FullName, entryMS.ToArray()); 
       } 

      } 
      else 
      { 
       entries.Add(entry.FullName, new byte[0]); 
      } 
     } 
    } 

    /////////////////////////// 
    // STEP 2: BUILD ZIP FILE 
    /////////////////////////// 
    using (var ms = new MemoryStream()) 
    using (var newArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
    { 
     foreach (var uncompressedEntry in entries) 
     { 
      var newEntry = newArchive.CreateEntry(uncompressedEntry.Key, newCompressionLevel); 
      using (var entryStream = newEntry.Open()) 
      using (var writer = new BinaryWriter(entryStream, Encoding.UTF8)) 
      { 
       writer.Write(uncompressedEntry.Value); 
      } 
     } 
     return ms.ToArray(); 
    } 
} 

:それは正しく構造アーカイブを作成

File.WriteAllBytes(@"D:\test.zip", ms.ToArray()); 

90mbなサイズが、何のファイルが抽出されません。

私がreturn ms.ToArray()で終わる場合、~130kbバイト配列を返します。

+0

まあ長い道のりには、新しいアーカイブにそれを一時場所に最初のアーカイブを解凍して再圧縮するだろう。 – Nkosi

答えて

1

完了する前にその内容をMemoryStreamから読み取るため、アーカイブが壊れています。アーカイブの作成を終了するには、ms.ToArray()を呼び出す前にnewArchive.Dispose()に電話する必要があります。あなたはこのようにそれを行うことができます。この特定のケースで :周り

using (var ms = new MemoryStream()) 
{ 
    using (var newArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) 
    { 
     foreach (var uncompressedEntry in entries) 
     { 
      var newEntry = newArchive.CreateEntry(uncompressedEntry.Key, newCompressionLevel); 
      using (var entryStream = newEntry.Open()) 
      using (var writer = new BinaryWriter(entryStream, Encoding.UTF8)) 
      { 
       writer.Write(uncompressedEntry.Value); 
      } 
     } 
    } 

    return ms.ToArray(); 
} 
+0

ありがとうございました! –

関連する問題