2010-02-23 133 views
2

我想知道是否可以從二進制文件中讀取一個字節爲「fstream」,然後更改該字節並將其寫回。 我試過這段代碼,但它沒有工作,沒有任何反應,但我確信它能正確讀取。C++,同時讀寫二進制文件

file.open(path, ios::in|ios::out|ios::binary|ios::ate); 
file.seekg(0, ios::end); 
int size=file.tellg(); 
file.seekg(0,ios::beg); 
char buffer;  
for(int i=0;i<size;i++) 
{ 
    file.read((char*)&buffer,sizeof(char)); 
    buffer=(buffer+7)%256; 
    file.write((char*)&buffer, sizeof(char)); 
} 

我應該採取的文件指針一個字節讀這樣回來後:

file.seekg(-1, ios::cur); 

在此先感謝。

+0

如果你在linux上,你可以使用mmap,它將文件映射到虛擬內存中。然後,您可以像訪問數組一樣訪問文件內容。 – 2010-02-23 09:45:02

+0

謝謝ar 我不是在linux中,但我會在linux上嘗試它,它一定很有趣。 – Auxiliary 2010-02-23 09:48:55

+0

Boost.Iostreams爲windows和posix平臺提供內存映射文件。 – 2010-02-23 10:10:49

回答

6

是的。正如您在問題中所建議的,如果您想覆蓋之前讀取的字節,則需要使用seekg調整文件指針的位置。每次讀取之後,文件指針將位於讀取字節之後。

1

讀寫使用相同的位置指針。因此,如果你想能夠讀取連續的值,爲了重寫一個值,你需要將指針倒回到被讀取的位置,對吧?

這就是說,在你的情況下,讀取數據塊可能更有效率,然後將它們轉換到內存中,然後寫回來。

2

您應該將指針移回先前讀取的字節數量;所以用char -1。

file.seekg(-1, std::ios::cur); 

不要認爲修改數據時必須具有相同的字節大小,否則會覆蓋文件中的其他數據。

0

首先,你必須經常檢查實際上打開了文件:

file.open(path, ios::in|ios::out|ios::binary|ios::ate); 
if (! file.is_open()) { 
    throw "open failed"; 
} 

然後,你必須經常檢查讀取&寫道:你期望的工作已經工作:

if (! file.read((char*)&buffer,sizeof(char))) { 
    throw "read failed"; 
} 

最後,你應該檢查你正在使用的打開標誌的組合是否在你的特定平臺上有效 - 有關這方面的一些討論,請參閱Why can't I read and append with std::fstream on Mac OS X? - 我建議在代碼中刪除ios :: ate標誌。