我有一种情况,文件中间有一个字节块需要洗牌。目前实现读取文件,洗牌内存中的字节,然后输出整个文件。虽然这可行,但它不适用于更大的文件大小。我还没有找到一个 C++ API,它允许我在特定偏移量处将特定数量的字节写入文件,而不会影响后面的字节。
这可以做到吗?
fstream
以(not ifstream
or )开头,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);
}
如果您使用的平台支持mmap()
(Linux 和其他 unix-likes - 但我很确定其他操作系统具有类似的 API,即使它没有被调用mmap()
),只需映射文件(或它的适当部分)进入您的地址空间,然后随机播放。