C#使用SharpZipLib库压缩大文件问题

C#使用SharpZipLib库压缩文件很简单,无非引入ICSharpCode.SharpZipLib.dll:
引用库文件
程序中引入对应的命名空间:

using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;

这样就可以进行压缩解压操作了,网上相关代码也很多,这里就不赘述了。但是今天调试时发现个内存溢出的问题:
内存溢出
看代码不难发现,这个缓存buffer创建的时候出现溢出。那么这个缓存创建了多大呢?fs.Length!!没错,文件多大咱就创建多大,这样相当于把整个文件放入内存,这还了得,网上果然只是示例代码,真正实用还得进行一番修改。
解决思路是开辟一个固定大小的缓存区,循环读取文件进行压缩,但是这里有个问题,压缩时是先写入ZipEntry再写入文件数据的,而ZipEntry里面包含了crc信息,不把文件读完,就计算不出来crc。所以我这里采用读取两遍文件的策略,第一遍计算crc,第二遍再写入文件数据。如果谁有更好的思路可以留言讨论。
修改之后,foreach循环里的代码如下:

int readlen = 4096000;
FileStream fs = File.OpenRead(item.Key.ToString());
byte[] buffer = new byte[4096000];       // 每次4M

ZipEntry entry = new ZipEntry(item.Key.Substring(dirPath.Length));
entry.DateTime = item.Value;
entry.Size = fs.Length;

long remaindSize = fs.Length;
// 计算crc
crc.Reset();
while (remaindSize > 0)
{
    if (remaindSize < readlen)
        readlen = (int)remaindSize;

    fs.Read(buffer, 0, readlen);
    remaindSize -= readlen;

    crc.Update(buffer, 0, readlen);
}
entry.Crc = crc.Value;
zipoutputstream.PutNextEntry(entry);

// 压缩数据
readlen = 4096000;
remaindSize = fs.Length;
fs.Seek(0, SeekOrigin.Begin);
while (remaindSize > 0)
{
    if (remaindSize < readlen)
        readlen = (int)remaindSize;

    fs.Read(buffer, 0, readlen);
    remaindSize -= readlen;
    zipoutputstream.Write(buffer, 0, readlen);
}
fs.Close();

这样改之后,再压缩大文件也就没有问题了。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值