3

ほぼ 8 GB のデータを含む zip ファイルを C# で作成したいと考えています。次のコードを使用しています。

using (var zipStream = new ZipOutputStream(System.IO.File.Create(outPath)))
{
    zipStream.SetLevel(9); // 0-9, 9 being the highest level of compression

    var buffer = new byte[1024*1024];

    foreach (var file in filenames)
    {
        var entry = new ZipEntry(Path.GetFileName(file)) { DateTime = DateTime.Now };

        zipStream.PutNextEntry(entry);

        var bufferSize = BufferedSize;
        using (var fs = new BufferedStream(System.IO.File.OpenRead(file), bufferSize))
        {
            int sourceBytes;
            do
            {
                 sourceBytes = fs.Read(buffer, 0, buffer.Length);
                 zipStream.Write(buffer, 0, sourceBytes);
             } while (sourceBytes > 0);
         }
     }

     zipStream.Finish();
     zipStream.Close();
 }

このコードは 1 GB 未満の小さなファイルには機能しますが、データが 7 ~ 8 GB に達すると例外をスローします。

4

2 に答える 2

5

他の人が指摘したように、実際の例外はこれに答えるのに大いに役立ちました。ただし、zip ファイルを作成する簡単な方法が必要な場合は、http: //dotnetzip.codeplex.com/ で入手できる DotNetZip ライブラリを試すことをお勧めします。Zip64 (つまり、4.2GB より大きいエントリと 65535 エントリ以上) をサポートしていることを知っているので、問題を解決できる可能性があります。また、ファイルストリームとバイト配列を自分で操作するよりもはるかに簡単に使用できます。

using (ZipFile zip = new ZipFile()) {
    zip.CompressionLevel = CompressionLevel.BestCompression;
    zip.UseZip64WhenSaving = Zip64Option.Always;
    zip.BufferSize = 65536*8; // Set the buffersize to 512k for better efficiency with large files

    foreach (var file in filenames) {
        zip.AddFile(file);
    }
    zip.Save(outpath);
}
于 2012-06-26T13:28:10.263 に答える
2

SharpZipLib を使用していますよね?どの例外がスローされるかわからないため、これが有効な解決策かどうかはわかりませんが、この投稿この投稿に基づいて、Zip64. 次のようなコードを使用して有効にします (2 番目のリンクされた投稿から)。

UseZip64 = ICSharpCode.SharpZipLib.Zip.UseZip64.Off

または、最初の投稿に基づいて、作成時にアーカイブのサイズを指定します。これにより、Zip64問題が自動的に処理されます。最初のリンクされた投稿から直接サンプル コード:

using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipFilePath)))
{
 //Compression level 0-9 (9 is highest)
 zipStream.SetLevel(GetCompressionLevel());

 //Add an entry to our zip file
 ZipEntry entry = new ZipEntry(Path.GetFileName(sourceFilePath));
 entry.DateTime = DateTime.Now;
 /* 
 * By specifying a size, SharpZipLib will turn on/off UseZip64 based on the file sizes. If Zip64 is ON
 * some legacy zip utilities (ie. Windows XP) who can't read Zip64 will be unable to unpack the archive.
 * If Zip64 is OFF, zip archives will be unable to support files larger than 4GB.
 */
 entry.Size = new FileInfo(sourceFilePath).Length;
 zipStream.PutNextEntry(entry);

 byte[] buffer = new byte[4096];
 int byteCount = 0;

 using (FileStream inputStream = File.OpenRead(sourceFilePath))
 {
     byteCount = inputStream.Read(buffer, 0, buffer.Length);
     while (byteCount > 0)
     {
         zipStream.Write(buffer, 0, byteCount);
         byteCount = inputStream.Read(buffer, 0, buffer.Length);
     }
 }
}
于 2012-06-26T13:08:14.960 に答える