シャッフルする必要があるファイルの途中にバイトのブロックがある場合があります。現在、実装はファイルを読み取り、メモリ内のバイトをシャッフルしてから、ファイル全体を出力します。これは機能しますが、より大きなファイル サイズには対応しません。後続のバイトに影響を与えることなく、特定のオフセットで特定のバイト数をファイルに書き込むことができる C++ API をまだ見つけていません。
これはできますか?
fstream
入力と出力の両方を行っているため、 (not ifstream
or ) から始めofstream
ます。
シャッフルを行うには、基本的に、seekg
変更を開始したい場所に到達するために を使用する必要があります。次にread
、シャッフルするデータを読み取るために使用します。次に、メモリ内のデータをシャッフルし、 を使用seekp
してそのデータを書き戻したい場所にシークし、最後に を使用write
してシャッフルされたデータをファイルに戻します。
これは簡単なデモです。「シャッフル」部分を文字どおりに取ります。文字列をファイルに書き込み、データの一部を読み取り、それらのバイトを並べ替えて、書き戻します。
#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 ライク - ただし、他の OS には、呼び出されていなくても同様の API があると確信していますmmap()
)、ファイル (またはその適切な部分) をマップするだけです。アドレス空間に入れ、その場でシャッフルします。