1

私は stdin に非常に大きな既知のバイト数を持っており、関心のある部分を読み取る前に大量の (既知の) それらのバイト数を破棄したいと考えています (つまり、大きな整数で前方に fseek したいのですが、fseek はそうではありません)。パイプには定義されていません)。これを実現する最も簡単な方法は、fgetc を多数呼び出すことです。最初の代替手段は、結果を格納するために割り当てられた大きなスクラッチ ポインターを使用して fread を 1 回呼び出すことです。1 つ目は非常に遅く、2 つ目は正当な理由もなく無制限の量のメモリを使用する可能性があります。複数の小さな読み取りを行うと、無制限のメモリ使用量の問題が解決されますが、フリー パラメーター (チャンク サイズ) が導入され、マシンと OS の組み合わせごとに異なる最速値を持つ可能性があります。

この目標をきちんと効率的に達成するための代替手段はありますか? POSIX を想定しています。

4

1 に答える 1

2

パイプ上のデータを「スキップ」する方法はありません。それを読み取る必要があります。

ブロックが非常に大きい場合は、(オーバーヘッドとメモリ使用量の妥協点として) 次のような中規模のバッファーを使用することをお勧めします。

 size_t dataToRead = some_large_number;

 while(dataToRead)
 {
    char buffer[4096];
    size_t toread = min(sizeof(buffer), dataToRead);
    size_t nread = fread(buffer, 1, toread, stdin);
    dataToRead -= nread;
 }

サイズ 4096 はかなり恣意的な選択ですが、入力に対して膨大な数の読み取りが発生しないように十分大きく、大量のスタックスペースを使用しないように十分小さいです。このサイズを変更することで、多くを得たり失ったりすることはほとんどありません。

于 2013-09-21T20:54:23.207 に答える