21人参与 • 2025-12-02 • Asp.net
.net framework自4.5版本起提供了system.io.compression命名空间,其中包含实现文件压缩和解压缩的核心类:
zipfile类 - 提供创建、提取和操作zip存档的静态方法
using system.io.compression; // 创建压缩文件 zipfile.createfromdirectory(@"c:\data", @"c:\archive.zip"); // 解压文件 zipfile.extracttodirectory(@"c:\archive.zip", @"c:\extracted");
gzipstream类 - 提供gzip数据格式的压缩和解压缩流
// 压缩文件
using (filestream originalfilestream = file.openread(@"c:\data.txt"))
using (filestream compressedfilestream = file.create(@"c:\data.gz"))
using (gzipstream compressionstream = new gzipstream(compressedfilestream, compressionmode.compress))
{
originalfilestream.copyto(compressionstream);
}
当需要更高级的功能时,可以考虑以下第三方库:
sharpziplib - 开源库,支持zip、gzip、tar和bzip2格式
using icsharpcode.sharpziplib.zip; // 创建zip文件 fastzip fastzip = new fastzip(); fastzip.createzip(@"c:\archive.zip", @"c:\data", true, "");
dotnetzip - 提供更简单的api和更好的性能
using ionic.zip;
// 创建带密码保护的zip
using (zipfile zip = new zipfile())
{
zip.password = "secret";
zip.addfile(@"c:\data.txt");
zip.save(@"c:\secure.zip");
}
日志文件压缩:定期压缩应用程序日志文件以节省存储空间
// 每周压缩日志文件
if (datetime.now.dayofweek == dayofweek.monday)
{
var logfiles = directory.getfiles(@"c:\logs", "*.log");
using (var zip = new zipfile())
{
zip.addfiles(logfiles);
zip.save($"logs_{datetime.now:yyyymmdd}.zip");
}
}
文件上传前压缩:减少网络传输数据量
// 上传前压缩用户文件
public byte[] compressfileforupload(string filepath)
{
using (var ms = new memorystream())
using (var gz = new gzipstream(ms, compressionmode.compress))
using (var file = file.openread(filepath))
{
file.copyto(gz);
return ms.toarray();
}
}
批量处理:压缩多个文件后统一发送
public void batchcompressandsend(string[] files, string outputpath)
{
using (var zip = new zipfile())
{
foreach (var file in files)
{
zip.addfile(file, "");
}
zip.save(outputpath);
sendtoserver(outputpath);
}
}
选择哪种方法取决于具体需求,内置类库适合基本需求,而第三方库则提供更多高级功能和更好的性能。
.net framework提供了system.io.compression命名空间来处理压缩和解压缩:
using system.io.compression; // 压缩单个文件 zipfile.createfromdirectory(@"c:\sourcefolder", @"c:\archive.zip"); // 解压缩文件 zipfile.extracttodirectory(@"c:\archive.zip", @"c:\destinationfolder");
// 使用gzipstream压缩文件
using (filestream originalfilestream = file.openread(@"c:\largefile.dat"))
using (filestream compressedfilestream = file.create(@"c:\largefile.dat.gz"))
using (gzipstream compressionstream = new gzipstream(compressedfilestream, compressionmode.compress))
{
originalfilestream.copyto(compressionstream);
}
// 使用gzipstream解压文件
using (filestream compressedfilestream = file.openread(@"c:\largefile.dat.gz"))
using (filestream outputfilestream = file.create(@"c:\largefile.dat"))
using (gzipstream decompressionstream = new gzipstream(compressedfilestream, compressionmode.decompress))
{
decompressionstream.copyto(outputfilestream);
}
当需要更多功能时,可以使用第三方库如sharpziplib:
using icsharpcode.sharpziplib.zip; using icsharpcode.sharpziplib.core; // 使用sharpziplib创建zip文件 fastzip fastzip = new fastzip(); fastzip.createzip(@"c:\archive.zip", @"c:\sourcefolder", true, ""); // 使用sharpziplib解压zip文件 fastzip.extractzip(@"c:\archive.zip", @"c:\destinationfolder", "");
// 压缩字节数组
public static byte[] compress(byte[] data)
{
using (var compressedstream = new memorystream())
using (var zipstream = new gzipstream(compressedstream, compressionmode.compress))
{
zipstream.write(data, 0, data.length);
zipstream.close();
return compressedstream.toarray();
}
}
// 解压字节数组
public static byte[] decompress(byte[] data)
{
using (var compressedstream = new memorystream(data))
using (var zipstream = new gzipstream(compressedstream, compressionmode.decompress))
using (var resultstream = new memorystream())
{
zipstream.copyto(resultstream);
return resultstream.toarray();
}
}
// 创建带密码的zip文件 zipoutputstream zipstream = new zipoutputstream(file.create(@"c:\secure.zip")); zipstream.password = "mypassword"; // 添加文件代码... zipstream.close(); // 解压带密码的zip文件 zipfile zipfile = new zipfile(@"c:\secure.zip"); zipfile.password = "mypassword"; // 解压代码...
zipoutputstream zipstream = new zipoutputstream(file.create(@"c:\split.zip")); zipstream.setlevel(5); // 压缩级别 zipstream.usezip64 = usezip64.on; // 支持大文件 zipstream.setsplitsize(10000000); // 每卷10mb // 添加文件代码... zipstream.close();
bufferedinputstream bis = new bufferedinputstream(new fileinputstream("largefile.dat"), 8192);
bufferedoutputstream bos = new bufferedoutputstream(new fileoutputstream("compressed.zip"), 8192);
zipoutputstream zos = new zipoutputstream(new fileoutputstream("output.zip"));
zos.setlevel(deflater.best_compression); // 设置为最高压缩率
public class zipmanager {
private static map<string, zipfile> zipfilecache = new concurrenthashmap<>();
public static zipfile getzipfile(string path) throws ioexception {
return zipfilecache.computeifabsent(path, p -> new zipfile(p));
}
}
附加建议:
在实际应用中,应该添加适当的错误处理:
try
{
zipfile.extracttodirectory(sourcezippath, extractpath);
}
catch (ioexception ex) when (ex.message.contains("already exists"))
{
// 处理文件已存在的情况
}
catch (unauthorizedaccessexception)
{
// 处理权限问题
}
catch (exception ex)
{
// 处理其他异常
}
在c#中进行跨平台解压时,主要面临以下几个技术挑战:
路径分隔符差异
windows使用反斜杠()作为路径分隔符,而linux/macos使用正斜杠(/)。当解压包含路径的文件时,可能导致路径解析错误。
文件名大小写敏感性问题
linux/macos文件系统区分文件名大小写,而windows不区分。解压后可能导致文件访问问题。
文件权限保留问题
unix系统中文件权限信息(如可执行权限)在windows上可能丢失或被忽略。
编码问题
不同平台对文件名编码的处理可能存在差异,特别是非ascii字符的文件名。
using system.io.compression;
// 解压zip文件
zipfile.extracttodirectory("archive.zip", "output_folder");
跨平台注意事项:
using icsharpcode.sharpziplib.zip;
// 解压zip文件
var fastzip = new fastzip();
fastzip.extractzip("archive.zip", "output_folder", null);
优势:
using ionic.zip;
// 解压zip文件
using (var zip = zipfile.read("archive.zip"))
{
zip.extractall("output_folder", extractexistingfileaction.overwritesilently);
}
特点:
path.combine()构建路径path.directoryseparatorchar代替硬编码分隔符string fullpath = path.combine("folder", "subfolder", "file.txt");
文件名规范化:
stringcomparer.ordinalignorecase进行文件名比较编码指定:
// 使用sharpziplib时指定编码
var zip = new zipfile("archive.zip") {
nametransform = new zipnametransform("output_folder"),
stringcodec = stringcodec.fromcodepage(encoding.utf8.codepage)
};
mono.posix库public async task<string> extractuploadedzip(iformfile zipfile, string extractpath)
{
// 确保目标目录存在
directory.createdirectory(extractpath);
// 保存上传的zip文件
var tempzippath = path.gettempfilename();
using (var stream = new filestream(tempzippath, filemode.create))
{
await zipfile.copytoasync(stream);
}
try
{
// 跨平台解压
zipfile.extracttodirectory(tempzippath, extractpath);
// 处理解压后的文件(如设置权限)
if (!runtimeinformation.isosplatform(osplatform.windows))
{
var files = directory.getfiles(extractpath, "*", searchoption.alldirectories);
foreach (var file in files)
{
// 设置unix权限(如644)
file.setunixfilemode(file, unixfilemode.userread | unixfilemode.userwrite
| unixfilemode.groupread | unixfilemode.otherread);
}
}
return extractpath;
}
finally
{
file.delete(tempzippath);
}
}
问题描述:当尝试在windows、linux或macos上创建或访问文件路径时,可能会遇到因路径包含系统保留字符而导致的错误。
详细解决方案:
system.io.path.getinvalidpathchars()方法获取当前操作系统不允许的字符列表public static string sanitizepath(string path)
{
var invalidchars = path.getinvalidpathchars();
return string.concat(path.where(c => !invalidchars.contains(c)));
}
问题背景:在linux/macos系统中,文件权限位(755、644等)对于程序执行至关重要,但windows创建的zip文件通常不保存这些信息。
解决方案选项:
file.setunixfilemode(filepath, unixfilemode.userread | unixfilemode.userwrite | unixfilemode.userexecute);
process.start("chmod", $"755 {filepath}");
典型场景:当解压由不同语言系统创建的压缩包时(如日文windows创建的zip在中文linux上解压),文件名可能出现乱码。
解决方案:
using (var archive = zipfile.openread(zippath))
{
var options = new ziparchiveencoding {
default = encoding.getencoding(932) // 日语shift-jis编码
};
// 使用指定编码处理条目
}
优化策略:
using (var zipstream = new zipinputstream(file.openread(zippath)))
{
zipentry entry;
while ((entry = zipstream.getnextentry()) != null)
{
using (var filestream = file.create(entry.name))
{
zipstream.copyto(filestream);
}
}
}
memorymappedfile处理超大文件路径处理:
path.combine()构建路径path.directoryseparatorchar)文件系统观察:
filesystemwatcher时要考虑不同系统的通知机制差异测试矩阵建议:
通过实施这些解决方案,可以显著提高c#解压功能在混合环境中的可靠性和兼容性。
到此这篇关于c#文件压缩与解压缩的多种实现方法的文章就介绍到这了,更多相关c#文件压缩与解压缩内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论