2010-09-29 226 views
3

我正在使用以下程序嘗試在C++中將文件src的內容複製到另一個dest。下面的代碼簡化給出:在C++中將一個文件的內容複製到另一個文件中

#include <fstream> 
using namespace std; 
int main() 
{ 
    fstream src("c:\\tplat\test\\secClassMf19.txt", fstream::binary); 
    ofstream dest("c:\\tplat\\test\\mf19b.txt", fstream::trunc|fstream::binary); 
    dest << src.rdbuf(); 
    return 0; 
} 

當我建立並執行在Windows中使用的代碼塊IDE與GCC編譯創建程序,一個名爲新文件「mf19.txt ......」,但沒有數據複製到它,並filesize = 0kb。我很積極,我在「... secClassMf19.txt」中有一些數據。

我遇到同樣的問題,當我在Windows的Visual C++ 2008

任何人都可以請幫忙解釋一下爲什麼我收到這個意外的行爲,更重要的是,如何解決這個問題編譯相同progeam?

+0

歡迎來到stackoverflow.com。下一次,pelase使用編輯窗口頂部的'101010'按鈕格式化您的代碼。另外,您可能想閱讀[FAQ](http://stackoverflow.com/faq)。 – sbi 2010-09-29 09:56:46

+0

當你說你確信你在secClassMf19.txt中有數據時,你是否真的在記事本中打開過它並查看了一下? – 2010-09-29 10:03:25

回答

4

您需要檢查在使用這些流之前打開文件是否實際成功。此外,它從來沒有傷害,以檢查是否一切順利事後。將您的代碼更改爲此並回報:

int main() 
{ 
    std::fstream src("c:\\tplat\test\\secClassMf19.txt", std::ios::binary); 
    if(!src.good()) 
    { 
     std::cerr << "error opening input file\n"; 
     std::exit(1); 
    } 
    std::ofstream dest("c:\\tplat\\test\\mf19b.txt", std::ios::trunc|std::ios::binary); 
    if(!dest.good()) 
    { 
     std::cerr << "error opening output file\n"; 
     std::exit(2); 
    } 
    dest << src.rdbuf(); 
    if(!src.eof()) 
     std::cerr << "reading from file failed\n"; 
    if(!dst.good()) 
     std::cerr << "writing to file failed\n"; 
    return 0; 
} 

我敢打賭,您會報告前兩次檢查中的一個命中。

如果打開輸入文件失敗,請嘗試使用std::ios::in|std::ios::binary而不是僅僅打開std::ios::binary

1

你有什麼理由不使用CopyFile函數嗎?

最佳

+0

我試過了sbi的建議(使用std :: ios :: in | std :: ios :: binary而不是std :: ios :: binary),程序仍然無法讀取輸入文件(返回1) 。即使按照gavinb的建議使用ifstream也沒有喜樂。 – 2010-09-29 11:09:40

+0

我剛剛見過Vagaus的建議。複製文件。但我早先已經嘗試過(添加#include 。那麼我使用的代碼是:CopyFile((LPCWSTR)「c:\\ tplat \ test \\ secClassMf19.txt」,(LPCWSTR)「c:\\ tplat \\ test \\ mf19b.txt「,true);但它也沒有工作,也許我做錯了什麼。 – 2010-09-29 11:14:00

1

經上所記,你src實例是一個普通的fstream時,你是不是指定爲輸入一個開放的模式。簡單的解決方案是使srcifstream的實例,並且您的代碼有效。 (僅添加一個字節!)

如果您已經測試了輸入流(如sbi建議),您會發現它沒有正確打開,這就是您的目標文件大小爲零的原因。它以寫入模式打開(因爲它是一個ofstream),截斷選項使其爲零,但寫入rdbuf()的結果簡單失敗,沒有寫入任何內容。

另一件需要注意的是,雖然這對小文件很好,但對於大文件來說效率會很低。現在,您正在將源文件的全部內容讀入內存,然後再將其寫入一個大塊中。這浪費了很多記憶。您最好以大塊閱讀(比如說1MB,適合磁盤緩存的合理大小)並一次寫入一個塊,最後一個塊是剩餘大小。要確定源文件的大小,您可以尋求最後的結果並查詢文件偏移量,然後知道正在處理的字節數。

如果你使用本地API,你可能會發現你的操作系統在複製文件時效率更高,但它的可移植性會降低。您可能需要查看Boost文件系統模塊以獲取便攜式解決方案。

+0

我試過了sbi的建議,它顯示讀取輸入文件的錯誤(retuen 1)。 – 2010-09-29 11:06:05

+0

我試過了sbi的建議(使用std :: ios :: in | std :: ios :: binary而不是std :: ios :: binary),程序仍然無法讀取輸入文件(返回1)甚至使用ifstream建議gavinb yiels沒有喜悅我剛剛見過Vagaus的建議wrt。CopyFile。但我已經嘗試過(加入#include 。我使用的代碼是:CopyFile((LPCWSTR)「c:\ \ tplat \ test \\ secClassMf19.txt「,(LPCWSTR)」c:\\ tplat \\ test \\ mf19b.txt「,true);但它也不起作用,並且該文件在NOTEPAD中打開,大小僅爲1KB。 – 2010-09-29 11:54:30

+0

@T J:它打開文件失敗或無法讀取文件? – sbi 2010-09-29 12:16:47

相關問題