2011-11-25 89 views
5

我想實現這樣的事情:閱讀從二進制模式文件塊到緩衝區,並書面緩衝到另一個文件

while (ifstream has not been entirely read) 
{ 
    read a chunk of data into a buffer that has size BUFLEN 
    write this buffer to ostream 
} 

起初我嘗試用ifstream.eof()爲我而實現這一目標條件,但我聽說這不是要走的路。我一直在尋找std :: ios :: ifstream的其他函數,但無法弄清楚還有什麼其他用途。

PS:我正在使用緩衝區,因爲正在傳輸的文件可能變得非常大。

回答

7

iostream類照顧所有必要的緩衝,所以你不要 必須。通常複製整個文件的習慣用法是:

fout << fin.rdbuf(); 

iostream負責所有必要的緩衝。 (這是一個 有點不尋常的使用<<,因爲它不格式。歷史 原因,毫無疑問。)

如果您需要的循環,也許是因爲你想重寫之前做的一些數據 轉換它,那麼它有點 竅門,因爲istream::read 「失敗」除非它讀取 請求的字符數。正因爲如此,你也必須檢查 多少個字中讀取,並對其進行處理,即使在讀取失敗:

int readCount; 
while (fin.read(&buf[0], buf.size()) 
     || (readCount = fin.gcount()) != 0) { 
    // ... 
    fout.write(&buf[0], readCount); 
} 

這是相當難看;更好的解決方案可能是將緩衝區包裝到 類中,併爲此類定義operator<<

+0

因此,如果我必須讀取一個非常大的文件並將其寫入其他文件,我不必擔心使用緩衝區,iostream已經這樣做了嗎?不過,我這樣做是因爲我在稍後階段通過TCP發送數據。感謝代碼,我現在會嘗試。 – codd

+0

雖然代碼工程雖然!謝謝! – codd

+0

在其他一些說明中:當我使用非文本文件時,這是否也適用?因爲我需要能夠用任何類型的文件(pdf,mp3,...)來做到這一點。它似乎沒有在我測試過的pdf上工作。 – codd

0

你的邏輯根本就是錯的。

你需要去了解它更多的是這樣的:

while (a chunk larger than zero could be read) 
{ 
    write chunk to output 
} 

看看上面就更簡單了?沒有必要明確檢查「文件結束」,只是讀取數據,直到失敗。然後你就完成了。

+0

我明白你的意思了。我試圖通過使用read()作爲條件來實現,但是read()給出了一個空文件,並且!read()保留了在拷貝之間用垃圾重寫我的文件。你介意闡述並給我使用特定的功能嗎? – codd

6

istream::read函數返回流,它可以作爲一個布爾表達式,所以你可以這樣做:

while (is.read(buffer, BUFLEN)) 
{ 
    outputfile.write(buffer, is.gcount()); 
} 

if (is.eof()) 
{ 
    if (is.gcount() > 0) 
    { 
     // Still a few bytes left to write 
     outputfile.write(buffer, is.gcount()); 
    } 
} 
else if (is.bad()) 
{ 
    // Error reading 
} 

你可能要檢查循環內寫沒有失敗過。

+0

下面的代碼給了我一個空的新文件,也許你知道它的問題是什麼? while(is.read(buffer,BUFLEN)){outfile.write(buffer,BUFLEN); }' – codd

+0

@codd擴展我的示例代碼。親自嘗試過。 –

+0

感謝示例代碼Joachim。這似乎也適用於其他文件,如pdf等! – codd