如何(重新)在文件中间写入字节?

时间:2013-04-24 20:59:01

标签: c++ file file-io io

我有一个案例,在文件中间有一个需要洗牌的字节块。目前实现读取文件,将内存中的字节混洗,然后输出整个文件。虽然这可行,但它不适用于较大的文件大小。我还没有找到一个C ++ API,它允许我在特定偏移量的文件中写入特定数量的字节,而不会影响后面的字节。

可以这样做吗?

2 个答案:

答案 0 :(得分:4)

fstream开始(不是ifstreamofstream),因为您同时进行输入和输出。

要进行改组,你基本上需要使用seekg来到你想要开始改变的地方。然后使用read来读取您要随机播放的数据。然后将内存中的数据洗牌,使用seekp寻找您要将数据写回的位置,最后使用write将混洗后的数据放回文件中。

这是一个快速演示,从字面上理解“shuffle”部分 - 它将一个字符串写入文件,然后读取一些数据,对这些字节进行排序,然后将它们写回:

#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>

void init(std::string const &name) { 
    std::ofstream initial(name);

    initial << "This is the initial data.";
}

void shuffle(std::string const &name) {
    std::fstream s(name);

    s.seekg(2);
    std::vector<char> data(5);
    s.read(&data[0], 5);
    std::sort(data.begin(), data.end());
    s.seekp(2);
    s.write(&data[0], 5);
}

void show(std::string const &name) { 
    std::ifstream in(name);

    std::copy(std::istreambuf_iterator<char>(in),
              std::istreambuf_iterator<char>(),
              std::ostream_iterator<char>(std::cout, ""));
}

int main() { 
    std::string name("e:/c/source/trash.txt");
    init(name);

    shuffle(name);

    show(name);
}

答案 1 :(得分:1)

如果您使用的是支持mmap()的平台(Linux和其他unix-like - 但我很确定其他操作系统有类似的API,即使它不是mmap()) ,只需将文件(或其中的相应部分)映射到您的地址空间,然后随意播放。