C# 缓冲 GZipStream 压缩

标签 c# multithreading

我正在写一个database备份功能,读取System.Diagnostics.Process object ,来自StandardOutput (StreamReader)属性(property)。我已成功写入纯文件。

//This code successfully wrote text files.
StreamWriter f = new StreamWriter(BackupPath);
while (true) {
  //RaiseProgressedEvent(new DBProgressEventArgs(dbsize, progress, "Writing backup file"));

  int buffsize = 512;
  char[] buff = new char[buffsize];
  int count = p.StandardOutput.ReadBlock(buff, 0, buff.Length);
  if (count == 0) break;
  // If no more data, trim the char array
  if (p.StandardOutput.Peek() < 0) buff = (from c in buff where c > 0 select c).ToArray();

  f.Write(buff, 0, count);
  progress += buffsize;
}
f.Close();

但是当我更改为GZipStream时:

//This code yields a broken gzip file.
//*2 lines changed: StreamWriter changed into FileStream.
FileStream fs = File.Create(BackupPath);
GZipStream zipStream = new GZipStream(fs, CompressionMode.Compress, true);

while (true) {
  RaiseProgressedEvent(new DBProgressEventArgs(dbsize, progress, "Writing backup file"));

  int buffsize = 512;
  char[] buff = new char[buffsize];
  int count = p.StandardOutput.ReadBlock(buff, 0, buff.Length);
  if (count == 0) break;
  if (p.StandardOutput.Peek() < 0) buff = (from c in buff where c > 0 select c).ToArray();

  //With UTF 8 Encoding, write to gzipstream.
  //f.write changed into the following 2 lines:
  Encoding enc = Encoding.UTF8;
  zipStream.Write(enc.GetBytes(buff), 0, enc.GetByteCount(buff));

  progress += buffsize;
}
fs.Close();

结果GZip文件不完整/损坏。当用 7zip 解压时然后用 notepad++ 打开,几乎所有文本都是好的,只有文件末尾附近的一些字节丢失了。我不确定,但也许错误就在附近:zipStream.Write(enc.GetBytes(buff), 0, enc.GetByteCount(buff)); 也许与enc.GetByteCount(buff)有关.

读取是为了多线程而缓冲的,用于处理大文件。那么...为什么最后一个字节丢失了?我哪里做错了?

最佳答案

尝试如下:

  • 使用GZipStream的构造函数,关闭FileStream post Dispose

    using(FileStream fs = File.Create(BackupPath))
    using(GZipStream zipStream = new GZipStream(fs, CompressionMode.Compress, false))
    {
    
     while (true) {
      RaiseProgressedEvent(new DBProgressEventArgs(dbsize, progress, "Writing backup file"));
    
     int buffsize = 512;
     char[] buff = new char[buffsize];
     int count = p.StandardOutput.ReadBlock(buff, 0, buff.Length);
     if (count == 0) break;
     if (p.StandardOutput.Peek() < 0) buff = (from c in buff where c > 0 select c).ToArray();
    
     //With UTF 8 Encoding, write to gzipstream.
     //f.write changed into the following 2 lines:
     Encoding enc = Encoding.UTF8;
     zipStream.Write(enc.GetBytes(buff), 0, enc.GetByteCount(buff));
    
     progress += buffsize;
    }
    }
    

关于C# 缓冲 GZipStream 压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39503393/

相关文章:

c# - 使用异步 CTP 同时下载 HTML 页面

c# - 如何将一行gridview的客户端id发送到javascript

java - 是否有一个 Java 线程池对象可以在可用内核之间自动对线程进行负载平衡,或者这是由 JVM 为您完成的?

python - Qt Designer实时显示python脚本的输出

ios - 相同的操作在两个相同的项目中执行时间不同

c# - MVVM-我应该在哪里实现我的保存逻辑?

C# - 将 WPF Image.source 转换为 System.Drawing.Bitmap

c# - 从 webapi c# 发送 POST 请求到 onesignal url

multithreading - 从 goroutine func 发出修改映射

java - tomcat中的阻塞与非阻塞主线程