一、单文件压缩
场景,文件可能比较大,需要压缩传输,比如上传和下载
/// <summary> /// 单文件压缩 /// </summary> /// <param name="sourceFile">源文件</param> /// <param name="zipedFile">zip压缩文件</param> /// <param name="blockSize">缓冲区大小</param> /// <param name="compressionLevel">压缩级别</param> public static void ZipFile(string sourceFile, string zipedFile, int blockSize = 1024, int compressionLevel = 6) { if (!File.Exists(sourceFile)) { throw new System.IO.FileNotFoundException("The specified file " + sourceFile + " could not be found."); } var fileName = System.IO.Path.GetFileNameWithoutExtension(sourceFile); FileStream streamToZip = new FileStream(sourceFile, FileMode.Open, FileAccess.Read); FileStream zipFile = File.Create(zipedFile); ZipOutputStream zipStream = new ZipOutputStream(zipFile); ZipEntry zipEntry = new ZipEntry(fileName); zipStream.PutNextEntry(zipEntry); //存储、最快、较快、标准、较好、最好 0-9 zipStream.SetLevel(compressionLevel); byte[] buffer = new byte[blockSize]; int size = streamToZip.Read(buffer, 0, buffer.Length); zipStream.Write(buffer, 0, size); try { while (size < streamToZip.Length) { int sizeRead = streamToZip.Read(buffer, 0, buffer.Length); zipStream.Write(buffer, 0, sizeRead); size += sizeRead; } } catch (Exception ex) { throw ex; } zipStream.Finish(); zipStream.Close(); streamToZip.Close(); }
说明:26行,blocksize为缓存区大小,不能设置太大,如果太大也会报异常。26-38行,把文件通过FileStream流,读取到缓冲区中,再写入到ZipOutputStream流。你可以想象,两个管道,一个读,另一个写,中间是缓冲区,它们的工作方式是同步的方式。想一下,能不能以异步的方式工作,读的管道只管读,写的管道只管写?如果是这样一个场景,读的特别快,写的比较慢,比如,不是本地写,而是要经过网络传输,就可以考虑异步的方式。怎么做,读者可以自行改造。关键一点,流是有顺序的,所以要保证顺序的正确性即可。
二、多文件压缩
这种场景也是比较多见,和单文件压缩类似,无非就是多循环几次。
/// <summary> /// 多文件压缩 /// </summary> /// <param name="zipfile">zip压缩文件</param> /// <param name="filenames">源文件集合</param> /// <param name="password">压缩加密</param> public void ZipFiles(string zipfile, string[] filenames, string password = "") { ZipOutputStream s = new ZipOutputStream(System.IO.File.Create(zipfile)); s.SetLevel(6); if (password != "") s.Password = Md5Help.Encrypt(password); foreach (string file in filenames) { //打开压缩文件 FileStream fs = File.OpenRead(file); byte[] buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); var name = Path.GetFileNa<div>本文来源gaodai.ma#com搞##代!^码7网</div>me(file); ZipEntry entry = new ZipEntry(name); entry.DateTime = DateTime.Now; entry.Size = fs.Length; fs.Close(); s.PutNextEntry(entry); s.Write(buffer, 0, buffer.Length); } s.Finish(); s.Close(); }