
64MBなどの特に大きなファイルがある場合は、ファイルの物理ハードドライブの場所を見つけて、特定のオフセットのバイトをファイルとして読み取ることができるかどうか疑問に思います。
ファイルの先頭で60MBオフセット100バイトに興味があるとしましょう。一部のアプリケーションレベルのeek()関数を使用している場合は、ファイルの先頭からファイルの終わりまで数百回のディスクスキャンを実行する必要がある非効率性は望ましくありません。
解決策はありますか?
とても感謝しています!
答え1
seek()
どのように行動すべきかについて誤解があるようです。中間バイトを読み取らずに、このオフセットのデータができるだけ効率的に格納される場所を見つけます。ブロックインデックスを検索するために複数のクエリ(おそらく数百回ではない)があります。
あなたができないことは、ファイルが開かれるときから次回開かれるまでのブロックインデックスの巡回を保存することです。オペレーティングシステムは、ファイルが最後に開かれてから変更または再配置されなかったことを覚えておく必要があります。
ファイルの内容は通常、隣接するディスクの場所にありません。ファイルは断片化される傾向があります。ファイルシステムは通常断片化を減らそうとしますが、通常これは保証されません。
答え2
もう一度読んでみると、根本的な質問に答えられなかったようです。
アプリケーション(実際にはカーネル)レベルで「照会」を使用しても、必ずしもディスクで「照会」コストがかかるわけではありません。ただ、ファイルハンドルに関連するオフセットを更新するだけです。
カーネルに読み書きを要求すると、そのオフセットをディスクオフセットに変換します。これを把握するためにブロックを読む必要があるかもしれませんが、最良のケースは直接訪問と同様に単一のルックアップコストです。
確かにこうすることが可能です。結局のところ、これはファイルシステムドライバがすることなので、他の人もそうすることができるはずです。必要なのは生ディスクへのアクセスだけです。
そこ はい ~の はい人々は既存のファイルシステムフォーマットに対してこれを行います。必要に応じてこれを手動で実行することもできます。
ファイルシステムが活発に使用されている場合、ディスク上のコンテンツは目に見えない方法で変更されるため、これをさらに困難にするいくつかの技術的な問題に直面しますが、それでも可能です。
カーネルに直接尋ねることもできます。xfs_bmapツールはこれを行うことができ、少なくとも一部のファイルシステムは同じインターフェースを実装しているため、直接要求できます。
場所を計算するにはカーネルと同じ検索回数が必要なので、実際に保存する可能性はほとんどありません。何もないこれを行います。
答え3
私はそうは思わない。
ファイルを開くと、開始(読み取り/書き込み)または終了(追加)になります。 「更新モード」でも、単にファイルの途中の特定の場所に到達しません。
私はあなたができる最善の方法はすでに外れていると思います。最初からオフセットを計算できる場合は、その場所を直接見つけてデータを読み取ることができます。その間に過度の読み込みが含まれるとは思わない。ファイルを開いた後、次の読み取りは計算されたオフセットになければなりません。