2014-05-16 139 views
0

我有一个文件拆分成多个段。我必须将这些文件合并到一个文件中。现在我想出的简单代码是:将多个文件段复制到一个文件中 - Qt

QFile file; 
file.setFileName(fileUrl); 
file.open(QIODevice::WriteOnly); 
for(int j=0;j<totalSegments;j++) 
{ 
    Segment[j]->fileSegment.close(); 
    if(!Segment[j]->fileSegment.open(QIODevice::ReadOnly)) 
    { 
     qDebug()<<"Segment not found"; 
     continue; 
    } 
    file.write(Segment[j]->fileSegment.readAll()); // is this really efficient and safe 
    Segment[j]->fileSegment.close(); 
    Segment[j]->fileSegment.remove(); 
} 

上面的代码片段在Windows和Linux上都能正常工作。但我有一些问题:

1-该方法是否真的有效。如果假设段的大小是以GB为单位的话,这会严重影响系统的性能,甚至可能由于RAM较少而损坏文件或失败。

2-上述方法在某些Linux发行版特别是Fedora中失败,如果总大小超过2GB。我没有测试过自己,但被许多人报告给我。

3-在Linux可以如果段上的文件系统EXT4和目标文件到其中的文件将NTFS系统上被写入它失败。它在Ubuntu上并没有失败,但许多用户抱怨说它确实如此。我不能只复制它。难道我做错了什么。

+1

readAll()在大文件上应该避免 - 如果由于巨大的大小(认为堆碎片)导致分配失败,它也可能容易失败。您应该循环阅读chunk-wise。最好在辅助线程中,如果你的程序有一个UI(以防止它被阻塞)。另外,检查所有read()和write()的返回值。后在循环每次写入防止失败的机会或改善上述代码 –

+0

@FrankOsterfeld不调用平齐。 –

+0

@adnankamili在每次写入_helps_之后调用flush以防止失败,但也会严重影响您的性能。 – Massa

回答

2

请避免一般每个问题有多个子问题,但我会尽力回答您的问题。

1是这个方法确实有效。如果假设段的大小是以GB为单位的话,这会严重影响系统的性能,甚至可能由于RAM较少而损坏文件或失败。

这是对于大文件非常糟糕的主意。我认为你希望建立块文件读写。

2-上述方法在某些Linux发行版特别是Fedora中失败,如果总大小超过2GB。我没有测试过自己,但被许多人报告给我。

2 GB <(或者它是4 GB?)在32位系统上算作大文件,所以他们有可能使用没有大文件支持构建的软件。有必要确保在构建时启用支持。曾经有一个Qt的配置选项,如-largefile

3-在Linux中,如果段位于EXT4文件系统上,并且文件将写入NTFS系统中的目标文件将会失败。它在Ubuntu上并没有失败,但许多用户抱怨说它确实如此。我不能只复制它。难道我做错了什么。

是的,它可能是同样的问题,你也需要注意内存碎片,这意味着即使你有2 GB可用,你将不能分配2 GB的内存,但内存是不恰当地分散。在Windows上,您可能希望在使用32位进程时使用/LARGEADDRESSAWARE选项。

总的来说,最好的办法是建立阅读和写作循环,然后你可以忘记大的地址意识等问题。如果您希望为您的客户提供支持,您仍然需要确保Qt可以处理大型文件。这当然仅在32位上是必需的,因为对于目前正在进行的文件大小的64位没有实际的限制。

既然你在评论请一些代码,让你去,这里是一个简单的和未经考验的版本块读取并输入文件的内容直接写入到输出文件。我相信这会让你走,所以你可以找出其余的。

QFileInfo fileInfo("/path/to/my/file"); 
qint64 size = fileInfo.size(); 
QByteArray data; 
int chunkSize = 4096; 
for (qint64 bytes = 0; bytes < size, bytes+=data.size()) { 
    data = myInputFile.read(chunkSize); 
    // Error check 
    myOutputFile.write(data); 
} 
+0

谢谢你这样一个很好的答案。我应该使用Qdatastream来写数据还是什么。块文件读写的一个简单例子会很棒。更快的读取写入的最佳块大小是多少? –

+0

@adnankamili:你打算支持二进制文件吗? – lpapp

+0

@adnankamili:我提出了一个未经检验的伪代码来证明这个想法。 – lpapp

相关问题