在c ++中以块的字节读写文件

时间:2013-11-14 18:08:28

标签: c++ file file-io seekg

我到处搜索它,但我似乎无法理解如何使用ios :: cur。我需要以10个字节的块读取整个文件,将这些字节写入缓冲区,然后将该缓冲区写入另一个文件。为此,我发送前10个字节,然后发送下一个10个字节,依此类推。但是我如何确保指针从最后一次迭代的位置开始?

char* data = 0;
int i = 0;
std::ifstream is("test.txt", std::ifstream::binary);

if (is)
{
    is.seekg(0, is.end);
    int size = is.tellg();

    cout << size << endl;

    ofstream obj;
    obj.open("new.txt");

    while (!is.eof())
    {
        for (; i <= size;)
        {
            is.seekg(i, is.beg);
            int sz = is.tellg();
            // cout<<sz<<endl;

            data = new char[sz + 1]; //  for the '\0'
            is.read(data, sz);

            data[sz] = '\0'; // set '\0' 
            cout << " data size: " << strlen(data) << "\n";
            cout << data;
            i = i + 10;
        }
        obj.close();
    }
}

2 个答案:

答案 0 :(得分:2)

您不需要重新定位文件位置。

每次读取操作后文件位置都会更新。

您应该使用两个文件对象,一个用于输入另一个用于输出。

在这两种情况下,每次读写操作后都会更新文件位置。

编辑1:简化示例

#define BUFFER_SIZE 16
unsigned char buffer[BUFFER_SIZE];
//...
while (input_file.read((char *)buffer, BUFFER_SIZE))
{
  output_file.write((char *)buffer, BUFFER_SIZE);
}

如果input_file位于偏移0处,那么在第一次读取之后,文件位置将为16.这可以通过以下方式验证:

int read_file_position = input_file.tellg();  
cout << "input file position: " << read_file_position << endl;
while (input_file.read((char *)buffer, BUFFER_SIZE))
{
  read_file_position = input_file.tellg();
  cout << "input file position: " << read_file_position << endl;
  output_file.write((char *)buffer, BUFFER_SIZE);
}

答案 1 :(得分:1)

我认为可以简化为:

char* data = 0;
int i = 0;
int size = 0;
int sz = 10;
std::ifstream is("test.txt", std::ifstream::binary);
std::ofstream obj;
data = new char[sz+1];
int read_sz = 0;

if (is)
{
    obj.open("new.txt");
    read_sz = is.tellg(); //we are at the beginning of the file now
    while (!is.eof())
    {
        int old_read_sz = read_sz; // old position - before next read
        is.read(data, sz);
        read_sz = is.tellg(); // new position, we've read read_sz-old_read_sz bytes
        data[read_sz-old_read_sz] = '\0'; // set '\0'
        // I hope you wanted the two lines below only for debugging purposes :)
        cout << " data size so far: " << read_sz << "\n";
        cout << data << endl;
        obj.write(data, read_sz-old_read_sz);
     }
    obj.close();
    is.close();
    cout << "total data size: "<< read_sz << endl;
}

一旦你读了一个数据块,你的文件光标已经移过那个块,所以你不需要自己重新定位它(从当前位置移动到结束/开始和返回可能是昂贵的 - 时间 - 特别是如果你有一个大的输入文件)。

顺便说一下,这是一个关于该主题的教程:http://www.cplusplus.com/doc/tutorial/files/

更新:忘记了is.read()!=旧的C风格阅读: - }