2009-11-17 175 views
0

我正在嘗試編寫一個小程序,它將搜索二進制文件中的幾個字節,並用另一堆字節替換這些文件。但每次我嘗試運行這個小應用程序時,我收到關於istream_iterator不可解除引用的消息。 也許有人有一個建議如何以另一種方式做到這一點(迭代器對我來說有點新主題)。修改二進制文件

#include <fstream> 
#include <iterator> 
#include <algorithm> 

using namespace std; 

int main() { 

typedef istream_iterator<char> input_iter_t; 

const off_t SIZE = 4; 
char before[SIZE] = { 0x12, 0x34, 0x56, 0x78 }; 
char after[SIZE] = { 0x78, 0x12, 0x34, 0x65 }; 

fstream filestream("numbers.exe", ios::binary | ios::in | ios::out); 

if (search(input_iter_t(filestream), input_iter_t(), before, before + SIZE) != input_iter_t()) { 
    filestream.seekp(-SIZE, ios::cur); 
    filestream.write(after, SIZE); 
} 

return 0; 
} 

這是我第二次嘗試這樣做,但也有一些錯誤。隨着小文件看起來像工程確定,但更大(大約2MB)它工作非常緩慢,從來沒有找到我正在尋找模式。

#include <iostream> 
#include <cstdlib> 
#include <string> 
#include <fstream> 
#include <iterator> 
#include <vector> 
#include <algorithm> 
#include <windows.h> 

using namespace std; 

int main() { 

const off_t Size = 4; 
unsigned char before[Size] = { 0x12, 0x34, 0x56, 0x78 }; 
unsigned char after[Size] = { 0x90, 0xAB, 0xCD, 0xEF }; 

    vector<char> bytes; 
    { 
     ifstream iFilestream("numbers.exe", ios::in|ios::binary); 
     istream_iterator<char> begin(iFilestream), end; 
     bytes.assign(begin, end) ; 
    } 

    vector<char>::iterator found = search(bytes.begin(), bytes.end(), before, before + Size); 
    if(found != bytes.end()) 
    { 
     copy(after, after + Size, found); 
     { 
      ofstream oFilestream("number-modified.exe"); 
      copy(bytes.begin(), bytes.end(), ostream_iterator<unsigned char>(oFilestream)); 
     } 
    } 
return 0; 
} 

乾杯, 托馬斯

回答

1

讀取文件的較大部分內存,在內存更換它,然後傾倒一堆磁盤。一次讀取一個字節是非常慢

我還建議你閱讀有關mmap(或在win32中的MapViewOfFile)。

0

search由於迭代器的性質而不能在istream_iterator上工作。這是一個輸入迭代器,這意味着它只是前進 - 這是因爲它從流中讀取數據,並且一旦從流中讀取,它就不能返回。 search需要一個轉發迭代器,它是一個輸入迭代器,您可以在其中停止,複製並向前移動一個,同時保留舊迭代器。前向迭代器的一個例子是一個單鏈表。你不能倒退,但你可以記住你的位置並從那裏重新開始。

速度問題是因爲矢量在處理未知數據方面確實很糟糕。每次空間用盡時,它會將整個緩衝區複製到新的內存中。將其替換爲deque,它可以處理逐個到達的數據。您還可能獲得改進的性能,試圖一次讀取數據流中的數據流,因爲按字符訪問是將整個文件加載到內存中的一種非常糟糕的方式。

0

假設文件不是太大,只需將文件讀入內存,然後根據需要修改內存緩衝區,然後將其寫回到文件中。

E.g. (未經測試):

FILE *f_in = fopen("inputfile","rb"); 
fseek(f_in,0,SEEK_END); 

long size = ftell(f_in); 
rewind(f_in); 

char* p_buffer = (char*) malloc (size); 
fread (p_buffer,size,1,f_in); 
fclose(f_in); 

unsigned char *p= (unsigned char*)p_buffer; 

// process. 

FILE *f_out = fopen("outoutfile","wb"); 
fwrite(p_buffer,size,1,f_out); 
fclose(f_out); 

free(p_buffer);