1

シャッフルする必要があるファイルの途中にバイトのブロックがある場合があります。現在、実装はファイルを読み取り、メモリ内のバイトをシャッフルしてから、ファイル全体を出力します。これは機能しますが、より大きなファイル サイズには対応しません。後続のバイトに影響を与えることなく、特定のオフセットで特定のバイト数をファイルに書き込むことができる C++ API をまだ見つけていません。

これはできますか?

4

2 に答える 2

4

fstream入力と出力の両方を行っているため、 (not ifstreamor ) から始め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);
}
于 2013-04-24T21:05:48.570 に答える
1

サポートするプラットフォームを使用している場合mmap()(Linux およびその他の UNIX ライク - ただし、他の OS には、呼び出されていなくても同様の API があると確信していますmmap())、ファイル (またはその適切な部分) をマップするだけです。アドレス空間に入れ、その場でシャッフルします。

于 2013-04-24T21:14:15.023 に答える