有效压缩多次复制同一文件的文件夹

3
我正在使用Ionic.Zip创建一个*.zip文件。然而,我的*.zip文件中包含多个相同的文件,有时甚至有20个副本,但ZIP格式根本没有利用这一点。
更糟糕的是,因为我正在将文件压缩到MemoryStream中,所以Ionic.Zip有时会崩溃并显示OutOfMemoryException。
是否有一个.NET库可以利用文件之间的冗余来进行压缩?
用户自己解压缩文件,因此不能使用奇异的格式。

1
为什么需要多次存储同一个文件? - We Are All Monica
它们位于不同的文件夹中。用户修改他想要的文件,然后将它们发送回来(他可能只想修改某些版本)。 - Tomas Grosup
通常应尝试消除信息的重复。如果同一文件用于多个目的,则可以创建一个映射文件,指示每个目的使用哪些文件。然后,用户可以修改映射文件,以指示给定目的应使用其选择的新文件。 - We Are All Monica
用户希望将其作为标准归档中的许多个体文件进行查看。 - Tomas Grosup
用户是错误的 :) 无论如何,zip格式应该极好地利用文件之间的冗余。 - We Are All Monica
2
你错了,zip格式会将每个文件单独压缩。 - Tomas Grosup
4个回答

4

我最终使用SharpZipLib库创建了一个tar.gz文件。对于1个文件,使用此解决方案,归档文件大小为3kB。如果在20个相同的文件上使用它,则归档文件仅为6kB,而在.zip中则为64kB。

Nuget:

Install-Package SharpZipLib

使用:

using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;

代码:

var output = new MemoryStream();
using (var gzip = new GZipOutputStream(output))
using (var tar = TarArchive.CreateOutputTarArchive(gzip))
            {
                for (int i = 0; i < files.Count; i++)
                {                    
                    var tarEntry = TarEntry.CreateEntryFromFile(file);                    
                    tar.WriteEntry(tarEntry,false);
                }

                tar.IsStreamOwner = false;
                gzip.IsStreamOwner = false;
            }

2
没有公开的API可以实现这种操作(例如GZip、PPMd、Zip和LZMA)。它们都是针对单个文件(或者更具体地说,是一组字节流)进行操作。
您可以将所有文件连接起来,使用tar-ball格式压缩算法进行压缩。
或者,您可以轻松地自己实现检查:为文件计算哈希值,并将其存储在哈希-文件名字典中。如果下一个文件的哈希值匹配,则可以决定您想要做什么,例如完全忽略此文件,或者记录其名称并将其保存在另一个文件中以标记重复文件。

3
“.tar.gz”很好用,因为它可以将所有文件打包并压缩。这个回答在技术上是正确的,因为它是使用“tar”和“gzip”的两个步骤,但大多数解压工具都可以轻松处理这个过程。 - Mike Precup
有没有用于创建.tar.gz的.NET库? - Tomas Grosup
@TomasGrosup 我自己从未以编程方式使用过它,但是有一个关于此问题的提问 - oleksii

2
是的,7-zip。有一个名为SevenZipSharp的库可以使用,但是根据我的经验,直接使用命令行启动压缩进程速度更快。
我的个人经验: 我们在公司中使用SevenZipSharp来解压缩高达1GB的存档文件,但它非常慢,直到我重新设计它,让它直接使用7-zip库运行其命令行界面。然后它的速度就像在Windows资源管理器中手动解压缩一样快。

直接使用命令行启动压缩进程速度更快。没有什么是一个好的System.Diagnostics.Process.Start()不能解决的 ;) - Nolonar

1

用户必须看到存档中的所有单个文件,而不仅是其中的一个。 - Tomas Grosup
1
@TomasGrosup:我不确定你的意思,双重压缩将允许您查看单个文件。 - Lie Ryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接