2014-05-16 63 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

相關問題