2013-10-29 49 views
2

我想用我的C++腳本讀取和寫入壓縮文件。爲此,我使用gzstream庫。它工作正常,像這樣一個很簡單的例子:用於C++的gzstream lib:創建的損壞文件

string inFile="/path/inputfile.gz"; 
igzstream inputfile; 
ogzstream outputfile("/path/outputfile.gz"); 
inputfile.open(inFile.c_str()); 

// Writing from input file to output file 
string line; 
while(getline(inputfile, line)) { 
    outputfile << line << endl; 
} 

但在我的C++腳本,事情就比較複雜,我的輸出文件的動態矢量內創建。

對於未壓縮的文件,這樣的工作非常細:

string inFile="/path/uncompressedInputFile.ext"; 
ifstream inputfile; 
vector <ofstream *> outfiles(1); 
string outputfile="/path/uncompressedOutputFile.ext"; 
outfiles[1] = new ofstream(outputfile.c_str()); 

inputfile.open(inFile.c_str()); 
string line; 
while(getline(inputfile, line)) { 
    *outfiles[1] << line << endl; 
} 
與壓縮文件

現在,這種方式會產生我損壞的文件:

string inFile="/path/compressedFile.gz"; 
igzstream inputfile; 
vector <ogzstream *> outfiles(1); 
string outputfile="/path/compressedOutputFile.gz"; 
outfiles[1] = new ogzstream(outputfile.c_str()); 

inputfile.open(inFile.c_str()); 
string line; 
while(getline(inputfile, line)) { 
    *outfiles[1] << line << endl; 
} 

我得到了一個「compressedOutputFile.gz」我路徑,而不是空的,但當試圖解壓縮它時,我得到了「意外的文件結尾」,我猜,這意味着文件已損壞.... 它有什麼問題?誰能幫幫我嗎 ?! :)

+0

爲什麼'[1]'(我們傾向於從0開始索引)? – doctorlove

+0

你是對的,指數通常從0開始,但將[0]代替爲[1]會得到相同的結果:/ – Totoro

回答

3

在這個簡單的例子中,當ofstream被銷燬時,GZip文件會自動關閉,將其剩餘的緩衝區刷新到磁盤。

在動態示例中,由於正在堆上創建對象,因此未關閉。在這兩種情況下,這可能會導致文件末尾的數據丟失,具體取決於格式。由於GZip是壓縮的,因此更可能失去更多相關數據,導致更明顯的失敗。

最好的解決方案是創建一個vector<unique_ptr<ogzstream> >,這會導致流在超出範圍時自動銷燬流。不太理想的解決方案是記住在退出函數之前手動刪除每個指針。

編輯:作爲一個快速提示,正如@doctorlove在原始評論中指出的那樣,您需要使用正確的索引,否則會導致其他問題。

+1

感謝您的解釋,現在看起來很明顯!添加「outfiles [0] - > close();刪除outfiles [0];」使它工作正常。 (我也改變了索引;))謝謝你幫助我:) – Totoro