如何报告在 QuaGzipFile(QuaZIP 库)上读取数据的进度 [英] how to report progress of data read on a QuaGzipFile (QuaZIP library)

查看:91
本文介绍了如何报告在 QuaGzipFile(QuaZIP 库)上读取数据的进度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Ubuntu 12.04 x86_64 上为 C++ 使用 QuaZIP 0.5.1 和 Qt 5.1.1.

I am using QuaZIP 0.5.1 with Qt 5.1.1 for C++ on Ubuntu 12.04 x86_64.

我的程序读取一个大的 gzip 二进制文件,通常是 1GB 或更多的未压缩数据,并对其进行一些计算.它的计算量并不大,大部分时间都在 I/O 上传递.所以如果我能找到一种方法来报告读取了多少文件数据,我可以在进度条上报告,甚至可以提供对 ETA 的估计.

My program reads a large gzipped binary file, usually 1GB of uncompressed data or more, and makes some computations on it. It is not computational-extensive, and most of the time is passed on I/O. So if I can find a way to report how much data of the file is read, I can report it on a progress bar, and even provide an estimation of ETA.

我用以下命令打开文件:

I open the file with:

QuaGzipFile gzip(fileName);
if (!gzip.open(QIODevice::ReadOnly))
{
    // report error
    return;
}

但是 QuaGzipFile 中没有找到文件大小和当前位置的功能.

But there is no functionality in QuaGzipFile to find the file size nor the current position.

我不需要找到未压缩流的大小和位置,压缩流的大小和位置就可以了,因为粗略估计进度就足够了.

I do not need to find size and position of uncompressed stream, the size and position of compressed stream are fine, because a rough estimation of progress is enough.

目前,我可以使用 QFile(fileName).size() 找到压缩文件的大小.此外,通过保留 gzip.read() 的返回值总和,我可以轻松找到未压缩流中的当前位置.但这两个数字不匹配.

Currently, I can find size of compressed file, using QFile(fileName).size(). Also, I can easily find current position in uncompressed stream, by keeping sum of return values of gzip.read(). But these two numbers do not match.

如果有帮助,我可以更改 QuaZIP 库,并访问与 zlib 相关的内部内容.

I can alter the QuaZIP library, and access internal zlib-related stuff, if it helps.

推荐答案

没有可靠的方法来确定未压缩流的总大小.有关详细信息和可能的解决方法,请参阅此答案.

There is no reliable way to determine total size of uncompressed stream. See this answer for details and possible workarounds.

但是,有一种方法可以在压缩流中获取位置:

However, there is a way to get position in compressed stream:

QFile file(fileName);
file.open(QFile::ReadOnly);
QuaGzipFile gzip;
gzip.open(file.handle(), QuaGzipFile::ReadOnly);
while(true) {
  QByteArray buf = gzip.read(1000);
  //process buf
  if (buf.isEmpty()) { break; }
  QFile temp_file_object;
  temp_file_object.open(file.handle(), QFile::ReadOnly);
  double progress = 100.0 * temp_file_object.pos() / file.size();
  qDebug() << qRound(progress) << "%";
}

这个想法是手动打开文件并使用文件描述符来获取位置.QFile 无法跟踪外部位置变化,因此 file.pos() 将始终为 0.因此我们从文件描述符创建 temp_file_object 迫使 QFile 请求文件位置.我可以使用一些较低级别的 API(例如 lseek())来获取文件位置,但我认为我的方式更跨平台.

The idea is to open file manually and use file descriptor to get position. QFile cannot track external position changes, so file.pos() will be always 0. So we create temp_file_object from the file descriptor forcing QFile to request file position. I could use some lower level API (such as lseek()) to get file position but I think my way is more cross-platform.

请注意,此方法不是很准确,并且可以给出比实际更大的进度值.这是因为 zlib 可以在内部读取和解码比您已经读取的数据更多的数据.

Note that this method is not very accurate and can give progress values bigger than real. That's because zlib can internally read and decode more data than you have already read.

这篇关于如何报告在 QuaGzipFile(QuaZIP 库)上读取数据的进度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆