2009-11-17 138 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);