【问题标题】:QDataStream and FlushQDataStream 和刷新
【发布时间】:2017-08-08 15:19:12
【问题描述】:

这是一个关于在 C++ 和 Linux 中使用 QDataStream 和 QTemporaryFile 的 QT 问题。

我在刷新 QDataStream 时遇到了一些问题。 QTextStream 有一个刷新功能,但是 QDataStream 显然不需要。 (2013 年的引文:http://www.qtcentre.org/threads/53042-QDataStream-and-flush())。我的问题是,实际上/仍然是这种情况,是否有强制 QDataStream 刷新?

当我处理使用 QDataStream 写入的文件时,最后的写入次数丢失(一次写入 5 个字节时为 112 个字节,一次写入 1 个字节时为 22 个字节)。但是,如果我在文件末尾写入大量填充,则所有内容都存在(除了最后几次写入的填充)。这就是为什么我相信 QDataStream 没有被刷新到文件中。

我正在处理的文件是中等大小的原始二进制文件(大约 2MB)。

这是一个使用我处理文件的一些代码的最小示例:

void read_and_process_file(QString &filename) {
  QFile inputFile(filename);
  if (!inputFile.open(QIODevice::ReadOnly)) {
    qDebug() << "Couldn't open: " << filename;
    return;
  }
  QDataStream fstream(&inputFile);
  QTemporaryFile *tempfile = new QTemporaryFile();
  if (!tempfile->open()) {
    qDebug() << "Couldn't open tempfile";
    return;
  }
  QDataStream ostream(tempfile);

  while (!fstream.atEnd()) {
    int block_size = 5;      //The number to read at a time
    char lines[block_size];

    //Read from the input file
    int len = fstream.readRawData(lines,block_size);
    QByteArray data(lines,len);

    //Will process data here once copying works

    //Write to the temporary file
    ostream.writeRawData(data,data.size());
  }
  process_file(tempfile);
  delete tempfile;
}

【问题讨论】:

  • 在调用process_file(tempfile)之前尝试调用tempfile-&gt;close()
  • 汉克,这似乎解决了问题,谢谢。如果临时文件关闭,是否有可能清理它?我会运行一些测试并检查一下。
  • 不,QTemporaryFile::close 不会删除文件。当QTemporaryFile 对象被销毁时,该文件被删除。另外我建议不要使用new 在单个范围内分配对象,因为这可能会导致内存泄漏。在您的示例中,您将在Couldn't open tempfile 之后发生泄漏。只需在堆栈上分配您的对象:QTemporaryFile tempfile;

标签: c++ qt


【解决方案1】:

此答案的第一部分与将文件刷新到磁盘的问题无关。


使用!fstream.atEnd() 作为while 的条件不是一个好主意。见http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong。我会将while 循环更改为:

const int block_size = 5;      //The number to read at a time
char lines[block_size];
int len = 0;
while ( (len = fstream.readRawData(lines,block_size)) > 0) {

    QByteArray data(lines, len);

    //Will process data here once copying works

    //Write to the temporary file
    ostream.writeRawData(data,data.size());
}

但是,我看不出使用中间 QByteArray 的意义。该循环可以简化为:

while ( (len = fstream.readRawData(lines,block_size)) > 0) {
    //Write to the temporary file
    ostream.writeRawData(lines, len);
}

如果您需要为其他事情处理QByteArray,可以构造一个并使用它,但对ostream.writeRawData的调用不需要使用它。


回复。文件没有被刷新的问题,我建议使用嵌套范围来打开文件。该文件应该在作用域结束时被刷新和关闭。

void read_and_process_file(QString &filename) {

   QFile inputFile(filename);
   if (!inputFile.open(QIODevice::ReadOnly)) {
      qDebug() << "Couldn't open: " << filename;
      return;
   }

   QDataStream fstream(&inputFile);
   QTemporaryFile *tempfile = new QTemporaryFile();
   if (!tempfile->open()) {
      qDebug() << "Couldn't open tempfile";
      return;
   }

   // Create a nested scope for the QDataStream
   // object so it gets flushed and closed when the 
   // scope ends.
   {
      QDataStream ostream(tempfile);

      const int block_size = 5;      //The number to read at a time
      char lines[block_size];
      int len = 0;
      while ( (len = fstream.readRawData(lines,block_size)) > 0) {

         QByteArray data(lines, len);

         //Will process data here once copying works

         //Write to the temporary file
         ostream.writeRawData(lines, len);
      }

      // The QDataStream should be flushed and
      // closed at the end of this scope.
   }

   process_file(tempfile);
   delete tempfile;
}

【讨论】:

  • 谢谢,好建议。我将循环更改为仅在 len
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 2019-08-04
  • 2012-04-25
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多