将多个文件段复制到一个文件中 - Qt

时间:2014-05-16 18:50:47

标签: c++ c linux windows 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-如果总大小超过2GB,上述方法在某些Linux Distro尤其是Fedora中失败。我没有测试过自己,但很多人都向我报告过。

3-在Linux中,如果段位于EXT4文件系统和目标文件上,则该文件将写入NTFS系统。它在Ubuntu上并没有失败,但很多用户都抱怨它确实如此。我不能只是复制它。我做错了什么。

1 个答案:

答案 0 :(得分:2)

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

  

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

对于大文件来说这是个坏主意。我想你希望建立读写块文件。

  

2-如果总大小超过2GB,上述方法在某些Linux Distro尤其是Fedora中失败。我没有测试过自己,但很多人都向我报告过。

2 GB&lt; (或者它是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);
}