System.IO. Compression.ZipArchive 适用于大文件

问题描述 投票:0回答:1

我有一个代码,它是用 C# 编写的用于压缩文件的 SSIS 脚本任务。

我在压缩 1GB(大约)文件时遇到问题。

我尝试实现此代码,但仍然收到错误“System.OutOfMemoryException”

System.OutOfMemoryException:引发了“System.OutOfMemoryException”类型的异常。
在ST_4cb59661fb81431abcf503766697a1db.ScriptMain.AddFileToZipUsingStream(字符串sZipFile,字符串sFilePath,字符串sFileName,字符串sBackupFolder,字符串sPrefixFolder)在c:\ Users \ dtmp857 \ AppData \ Local \ Temp sta \ 84bef43d323b439ba25df 47c365b5a29\ScriptMain.cs:第 333 行
在 c:\Users\dtmp857\AppData\Local\Temp sta\84bef43d323b439ba25df47c365b5a29\ScriptMain.cs 中的 ST_4cb59661fb81431abcf503766697a1db.ScriptMain.Main() 处:第 131 行

这是压缩文件时的代码片段:

protected bool AddFileToZipUsingStream(string sZipFile, string sFilePath, string sFileName, string sBackupFolder, string sPrefixFolder)
{
    bool bIsSuccess = false;

    try
    {
        if (File.Exists(sZipFile))
        {
            using (ZipArchive addFile = ZipFile.Open(sZipFile, ZipArchiveMode.Update))
            {
                addFile.CreateEntryFromFile(sFilePath, sFileName);

                //Move File after zipping it
                BackupFile(sFilePath, sBackupFolder, sPrefixFolder);
            }
       }
       else
       {
       //from https://stackoverflow.com/questions/28360775/adding-large-files-to-io-compression-ziparchiveentry-throws-outofmemoryexception
           using (var zipFile = ZipFile.Open(sZipFile, ZipArchiveMode.Update))
           {
               var zipEntry = zipFile.CreateEntry(sFileName);

               using (var writer = new BinaryWriter(zipEntry.Open()))
               using (FileStream fs = File.Open(sFilePath, FileMode.Open))
               {
                   var buffer = new byte[16 * 1024];

                   using (var data = new BinaryReader(fs))
                   {
                        int read;

                        while ((read = data.Read(buffer, 0, buffer.Length)) > 0)
                            writer.Write(buffer, 0, read);
                   }
               }
          }

          //Move File after zipping it
          BackupFile(sFilePath, sBackupFolder, sPrefixFolder);
      }

      bIsSuccess = true;
  }

  catch (Exception ex)
  {
     throw ex;
  }

  return bIsSuccess;
}

我缺少什么,请给我建议,也许是教程或处理这个问题的最佳实践。

c# ssis c#-ziparchive
1个回答
2
投票

我知道这是一篇旧帖子,但我能说什么,它帮助我整理了一些东西,并且仍然成为 Google 上的热门内容。

所以System.IO.Compression库肯定有问题! 首先也是最重要的...

您必须确保关闭 32-Preferred。拥有这个设置(在我的例子中是为“AnyCPU”构建的)会导致许多不一致的问题。

话虽如此,我拿了一些演示文件(几个小于 500MB,一个为 500MB,一个为 1GB),并创建了一个带有 3 个按钮的示例程序,使用了 3 种方法。

Button 1 - ZipArchive.CreateFromDirectory(AbsolutePath, TargetFile);
Button 2 - ZipArchive.CreateEntryFromFile(AbsolutePath, RelativePath);
Button 3 - Using the [16 * 1024] Byte Buffer method from above

现在事情变得有趣了。 (假设该程序被构建为“AnyCPU”并且没有 32 Preferred 检查)...所有 3 种方法都可以在 Windows 64 位操作系统上运行,无论它有多少内存。

但是,当我在 32 位操作系统上运行相同的测试时,无论它有多少内存,只有方法 1 有效!

方法 2 和 3 因内存不足错误而崩溃,并且为了添加盐,方法 3(首选的分块方法)实际上比方法 #2 损坏了更多的文件!

我所说的混乱,是指我的文件中,500MB 和 1GB 文件最终出现在压缩存档中,但大小小于原始文件(基本上被截断了)。

所以我不知道...因为现在已经没有很多 32 位操作系统了,我想这可能是一个没有实际意义的问题。

但似乎 System.IO.压缩框架中存在一些错误!

© www.soinside.com 2019 - 2024. All rights reserved.