1

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

这可以做到吗?

4

2 回答 2

4

fstream以(not ifstreamor )开头,ofstream因为您同时进行输入和输出。

要进行改组,您基本上需要使用seekg到达您想要开始更改内容的位置。然后read用来读取你要洗牌的数据。然后 shuffle 内存中的数据,使用seekp回溯到要写回数据的位置,最后使用write将 shuffle 后的数据放回文件中。

这是一个快速演示,从字面上理解“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);
}
于 2013-04-24T21:05:48.570 回答
1

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

于 2013-04-24T21:14:15.023 回答