【问题标题】:How do I (re)write bytes in the middle of a file?如何(重新)在文件中间写入字节?
【发布时间】:2013-04-18 14:22:30
【问题描述】:

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

这个可以吗?

【问题讨论】:

  • 只需使用seekg,然后在新位置写入即可。后面的字节不会受到影响。
  • 如果你需要在中间addremove字节,那是文件系统的限制,而不是C++ API。

标签: c++ file file-io io


【解决方案1】:

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);
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-12
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      相关资源
      最近更新 更多