ファイルの種類を判別できる stat (ほとんどの Unix システムで使用されている) に代わるものはありますか? マンページによると、stat の呼び出しはコストが高く、アプリでかなり頻繁に呼び出す必要があります。
5 に答える
別の方法はfstat()
、既にファイルを開いている場合です (そのため、そのファイル記述子があります)。またはlstat()
、シンボリックリンクが指すファイルではなく、シンボリックリンクについて知りたい場合。
man ページはコストを誇張していると思います。ファイルの名前を inode に解決しなければならない他のシステム コールよりも、それほど悪くはありません。よりもコストがかかりgetpid()
ます。よりも安価ですopen()
。
あなたに与える「ファイルタイプ」stat()
は、ファイルが通常のファイルであるか、デバイスファイルやディレクトリのようなものであるか、とりわけそのサイズやiノード番号などです。それがあなたが知る必要があることであるならば、あなたはを使わなければなりませんstat()
。
実際に知る必要があるのがファイルの内容のタイプ(テキストファイル、JPEG画像、MP3オーディオなど)である場合、2つのオプションがあります。ファイル名拡張子(「.mp3」で終わる場合、ファイルにはおそらくMP3オーディオが含まれています)に基づいて推測できます。または、実際にファイルを開き、その内容の一部を読み取ってファイルが何であるかを把握するlibmagicを使用できます。libmagicのアプローチはより高価ですが(回避しようとしている場合はstat()
、おそらく回避したいと思うでしょうopen()
)、エラーが発生しにくくなります(たとえば、「。mp3」ファイルが実際にはJPEGイメージである場合)。
一部のファイルシステムを備えた Linux では、ファイル タイプ (通常、char デバイス、ブロック デバイス、ディレクトリ、パイプ、シンボリック リンクなど) は linux_dirent 構造体に格納されます。これは、カーネルが getdents システム コールを介してアプリケーション ディレクトリ エントリを提供するものです。 . 必要な stat 構造内の唯一のものはファイル タイプであり、ディレクトリのすべてまたは多くのエントリに対してそれを取得する必要がある場合、(readdir ではなく) getdents を直接使用して、そこからファイル タイプを取得しようとすることができます。 linux_dirent で無効なファイル タイプが見つかった場合にのみ stat を使用します。アプリケーションのファイルシステムの使用パターンによっては、Linux を使用している場合、これは stat を使用するよりも高速になる可能性がありますが、多くの場合、stat は高速になるはずです。
Stat の速度は、要求されているデータをディスク上で見つけることに大きく関係しています。ディレクトリを再帰的にトラバースしてすべてのファイルを統計する場合、各統計は全体的にかなり高速になるはずです。これは、統計に必要なデータを取得する作業のほとんどが、以前の stat の呼び出しによってカーネルに要求する前にキャッシュされるためです。 . 一方、システム全体にランダムに分散された同じ数のファイルを統計する場合、カーネルは、統計を呼び出すファイルごとにディスクからいくつかのディレクトリを読み取る必要がある可能性があります。
fstat は常に非常に高速である必要があります。これは、ファイルがオープン状態になるためにカーネルがアクセスする必要があるため、必要なデータが既に RAM にあるはずであり、カーネルがトラブルを経験する必要がないためです。ファイル名のパスをたどって、各コンポーネントがRAMまたはディスク上にあるかどうかを確認し、ディスクからディレクトリを読み取る可能性があります(ただし、そうする必要はない可能性があります)が、要求しているデータがRAMにあることを発見するだけです。
そうは言っても、開いているファイルで stat を呼び出すと、開いていないファイルで呼び出すよりも高速になるはずです。
*nix システムの "magic" ファイルを知っていますか? コマンドラインから次のような方法でファイルをクエリするとfile myfile.ext
、実際のファイルの種類を取得できます。
これは、拡張子を見るのではなく、ファイルの内容を読み取ることによって行われ、*nix (Linux、Unix、...) システムで広く使用されています。
あなたのアプリケーションが Linux システムで動作することが期待されるなら、inotify(7) を試してみませんか。stat
多くのファイルを ing するよりも確実に高速です。