2017-08-08 79 views
0

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

我有一些问题得到一个QDataStream刷新。 QTextStream有一个flush函数,但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; 
} 
+1

在调用'process_file(tempfile)'之前尝试调用'tempfile-> close()'。 – hank

+0

汉克,这似乎消除了这个问题,谢谢。如果临时文件被关闭,是不是有可能清理掉它?我将运行一些测试并检查它。 –

+1

不,'QTemporaryFile :: close'不会删除文件。当QTemporaryFile对象被销毁时,该文件被删除。此外,我会建议不要使用'new'在单个作用域内分配对象,因为这可能会导致内存泄漏。在你的例子中,你会在'无法打开临时文件'后发生泄漏。只需在堆栈上分配你的对象:'QTemporaryFile tempfile;' – hank

回答

2

这个答案的第一部分是独立的冲洗到磁盘文件的问题。


使用!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点。该循环可以简化为:如果您需要处理QByteArray其他的东西

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

,它的罚款,以构建一个使用它,但调用ostream.writeRawData并不需要使用它。


Re。该文件的问题没有得到刷新,我会建议使用嵌套的范围来打开文件。该文件应该在范围的末尾被刷新并关闭。

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; 
} 
+0

谢谢,很好的建议。我改变了循环,只有当你的原始评论建议len <= 0时才结束。你是对的,QByteArray不是一个简单的例子。不幸的是,虽然这很有用,但它不能解决问题。 –

+0

@Weir_Doe,查看更新。 –