
64 MB など特に大きなファイルがある場合、ファイルの物理的なハード ドライブの場所を特定し、特定のオフセットからファイルにバイトを読み込むことは可能でしょうか?
たとえば、ファイルの先頭から 60 MB のオフセットを持つ 100 バイトに関心があるとします。アプリケーション レベルの seek() 関数を使用した場合、ファイルの先頭からファイルの末尾まで取得するのに数百回のディスク シークが必要になるため、効率が悪くなります。
解決策はありますか?
本当にありがとう!
答え1
の動作について誤解しているようですseek()
。 は、介在するバイトを読み取らずに、このオフセットのデータが格納されている場所を可能な限り効率的に特定します。 ブロック インデックスをトラバースするには、数回のシーク (数百ではない可能性が高い) が必要です。
できないのは、ファイルを開いたときから次のファイルを開くまでのブロック インデックスのトラバースを保存することです。OS は、ファイルが最後に開かれてから変更または再配置されていないことを記憶する必要がありますが、これには、わずかな潜在的なメリットのために大量のデータを記憶する必要があります。
一般的に、ファイルの内容は連続したディスク位置には存在しないことに注意してください。ファイルは断片化される傾向があります。ファイルシステムは通常、断片化を減らすように努めますが、一般的にはこれが保証されるわけではありません。
答え2
読み返してみると、根本的な質問に答えていないような気がします。
アプリケーション (実際にはカーネル) レベルで「シーク」を使用すると、必ずしもディスク上で「シーク」が発生するわけではありません。ファイル ハンドルに関連付けられたオフセット番号を更新するだけです。
カーネルに読み取りまたは書き込みを要求すると、カーネルはそのオフセットをディスク オフセットに変換します。この変換にはブロックの読み取りが必要になる場合がありますが、直接アクセスする場合と同様に、最良の場合でも 1 回のシークのコストがかかります。
それは絶対に可能です。結局のところ、ファイル システム ドライバーがまさにそれを行うので、他の人にもできるはずです。必要なのは、raw ディスクへのアクセスだけです。
そこには は の 例既存のファイル システム フォーマットに対してこれを実行する人はたくさんいます。必要に応じて手動で実行することもできます。
ファイル システムがアクティブに使用されている場合は、ディスク上のコンテンツが目に見えない形で変更されるため、実行が困難になる技術的な課題がいくつかありますが、それでも可能です。
カーネルに直接問い合わせることもできます。xfs_bmapツールはそれを実行し、少なくとも一部のファイル システムは同じインターフェイスを実装しているため、直接問い合わせることができます。
ただし、位置の計算にはカーネルが行うのと同じ数のシークが必要になるため、実際には節約できない可能性が高い。何でもこれをやっています。
答え3
私はそうは思わない。
ファイルを開くと、先頭 (読み取り/書き込みの場合) または末尾 (追加の場合) に移動します。「更新モード」の場合でも、ファイルの途中の指定された場所に移動するわけではありません。
できる最善のことは、すでに述べたとおりだと思います。つまり、最初からオフセットを計算できれば、その場所を直接探してデータを読み取ることができます。この方法では、途中で過剰な読み取り操作が発生することはないと思います。ファイルを開いた後の次の読み取りは、計算されたオフセットで行われるはずです。