3

大きなファイル (2.5GB) をスキャンして文字列を抽出し、数百のファイルのサブセットに書き込むプロジェクトがあります。

通常のバッファリングされた書き込みを使用するのが最も速いでしょうが、

  1. ファイルハンドルがなくなるのが心配です。
  2. ファイルの書き込み中にファイルの進行状況を監視できるようにしたい。
  3. プロセスが中断された場合の損失をできるだけ少なくしたいと考えています。不完全なファイルはまだ部分的に役立ちます。

代わりに、読み取り/書き込みモードで開き、新しい行を追加して、もう一度閉じます。

これはほとんどの場合十分に高速でしたが、特定の OS ではこの動作が深刻な悲観論であることがわかりました。前回 Windows 7 ネットブックで実行したときは、数日後に中断しました。

非常に多くのファイルを開いたままにし、それぞれ非常に多くの書き込み操作の後にフラッシュする、ある種の MRU ファイルハンドル マネージャーを実装できます。しかし、これはやり過ぎですか?

これは一般的な状況であるに違いありません。「ベスト プラクティス」や「パターン」はありますか?

現在の実装は Perl であり、Linux、Solaris、および Windows、ネットブックからファット サーバーで実行されています。しかし、私は一般的な問題に興味があります: 言語に依存せず、クロスプラットフォームです。C または node.js で次のバージョンを作成することを考えています。

4

1 に答える 1

2

Linux では、多くのファイル (数千) を開くことができます。setrlimit syscall とulimitシェルビルトインを使用して、1 つのプロセスで開かれるハンドルの数を制限できます。getrlimitsyscall と/proc/self/limits (または/proc/1234/limitspid 1234 のプロセスに対して)を使用してそれらをクエリできます。システム全体で開いているファイルの最大数は thru です/proc/sys/fs/file-max(私のシステムでは、1623114 あります)。

そのため、Linux ではわざわざ多くのファイルを一度に開くことができませんでした。

また、開いているファイルのメモ化された キャッシュを維持し、可能であればそれらを (MRU ポリシーで) 使用することをお勧めします。各ファイルをあまり頻繁に開いたり閉じたりしないでください。何らかの制限に達した場合にのみ行ってください... (例:openが失敗した場合)。

言い換えれば、structファイル名を知っている独自のファイル抽象化 (または単に ) を持ち、開いているFILE*(または null ポインター) を持ち、現在のオフセットを保持し、最後に開いたり書いたりしてから管理することができます。 FIFO 分野でのそのようなもののコレクション (open を持っている人向けFILE*)。ファイル記述子をあまりにも頻繁closeに (そして後で再) することは確かに避けたいと思います。open

ときどき (つまり、数分に 1 回) sync(2)を呼び出すこともできますが、あまり頻繁に呼び出さないでください (10 秒に 1 回を超えないようにしてください)。buffered FILE-s を使用する場合は、時々それらを忘れないでくださいfflush。繰り返しますが、それを頻繁に行わないでください。

于 2012-09-06T21:29:18.867 に答える