ちょっとした質問があります:
たとえば、.NET Framework の System.IO.File.Copy() メソッドを使用しています。このメソッドは、WinAPI の CopyFile() 関数のマネージ ラッパーです。しかし、CopyFile 関数はどのように機能するのでしょうか? HDDのファームウェアとやり取りするか、アセンブラーまたはその他の何かを介して他の操作を実行する可能性があります...
最高レベルから最低レベルまでどのように見えますか?
ちょっとした質問があります:
たとえば、.NET Framework の System.IO.File.Copy() メソッドを使用しています。このメソッドは、WinAPI の CopyFile() 関数のマネージ ラッパーです。しかし、CopyFile 関数はどのように機能するのでしょうか? HDDのファームウェアとやり取りするか、アセンブラーまたはその他の何かを介して他の操作を実行する可能性があります...
最高レベルから最低レベルまでどのように見えますか?
一番下から始めて、上に向かって作業することをお勧めします。
ディスク ドライブは、最も低いレベルで、セクタ、トラック、およびヘッドのコレクションに編成されます。セクターはトラックのセグメントであり、トラックはディスク自体の領域であり、プラッターがその下で回転するときのヘッド位置によって表され、ヘッドはプラッターからデータを読み取る実際の要素です。
トラックはディスクの中心からヘッドまでの距離に基づいて測定されるため、ディスクの中心に向かってトラックの「長さ」がディスクの外側の端よりも短いことがわかります。
セクタはトラックの一部であり、通常は固定長です。そのため、内側のトラックは外側のトラックよりも少ないセクターを保持します。
このディスク ジオメトリの多くは、現在ではドライブ コントローラ自体によって処理されますが、以前は、この構成はオペレーティング システムとディスク ドライバによって直接管理されていました。
ドライブの電子回路とディスク ドライバが協力して、ディスクを一連の固定長ブロックとして表現しようとします。
したがって、10MB のドライブがあり、512 バイトのディスク ブロックを使用する場合、そのドライブの容量は 20,480 "ブロック" になることがわかります。
このブロック編成は、他のすべてが構築される基盤です。この機能があれば、ディスク ドライバーとドライブ コントローラーを介して、ディスク上の特定のブロックに移動し、そのブロックに新しいデータを読み書きするように指示できます。
ファイル システムは、このブロックのヒープを独自の構造に編成します。FS は、どのブロックがどのファイルによって使用されているかを追跡する必要があります。
ほとんどのファイル システムには、「起動する場所」が固定されています。つまり、起動時にディスク レイアウトに関する情報を見つけようとする場所です。
ディレクトリを持たず、8 文字の名前と 3 文字の拡張子、1 バイトのステータス情報、およびファイルがディスク上で始まるブロック番号用の 2 バイトを持つファイルをサポートする粗いファイル システムを考えてみましょう。また、システムには 1024 ファイルのハード リミットがあると仮定することもできます。最後に、ディスク上のどのブロックが使用されているかを知る必要があります。そのために、ブロックごとに 1 ビットを使用します。
この情報は、一般に「ファイル システム メタデータ」と呼ばれます。ディスクが「フォーマット」されると、最近では新しいファイル システム メタデータを書き込むだけです。昔は、セクタ マークやその他の情報を空の磁気メディア (一般に「ロー レベル フォーマット」と呼ばれる) に実際に書き込むことが問題でした。現在、ほとんどのドライブはすでにローレベル フォーマットになっています。
この大雑把な例では、ディレクトリ用のスペースと、どのブロックが使用されているかを示すデータである「目次」用のスペースを割り当てる必要があります。
また、OS が最初の 16 ブロックを「ブート セクタ」などに使用できるように、ファイル システムはブロック 16 から開始する必要があるとも言います。
したがって、ブロック 16 では、14 バイト (各ファイル エントリ) * 1024 (ファイル数) = 12K を格納する必要があります。それを 512 (ブロックサイズ) で割ると 24 ブロックになります。10MB ドライブの場合、20,480 ブロックあります。20,480 / 8 (8 ビット/バイト) は、2,560 バイト / 512 = 5 ブロックです。
ディスクで使用可能な 20,480 ブロックのうち、ファイル システム メタデータは 29 ブロックです。OS の 16 を追加すると、20,480 のうち 45 ブロックになり、20,435 の「空きブロック」が残ります。
最後に、各データ ブロックは、ファイル内の次のブロックを指す最後の 2 バイトを予約します。
ここで、ファイルを読み取るには、ディレクトリ ブロックでファイル名を検索します。そこから、ファイルの最初のデータ ブロックへのオフセットを見つけます。そのデータ ブロックを読み取り、最後の 2 バイトを取得します。これらの 2 バイトが 00 00 の場合、それがファイルの終わりです。それ以外の場合は、その番号を取得してそのデータ ブロックを読み込み、ファイル全体が読み込まれるまで続けます。
ファイル システム コードは最後にポインタの詳細を隠し、プログラムで使用するためにブロックをメモリにロードするだけです。プログラムが read(buffer, 10000) を実行すると、バッファがいっぱいになるまで、またはファイルの終わりに到達するまで、ディスクからデータのいくつかのブロックを読み取ることになることがわかります。
ファイルを書き込むには、システムはまずディレクトリに空き領域を見つける必要があります。それを取得すると、TOC ビットマップで空きブロックを見つけます。最後に、データを取得し、ディレクトリ エントリを書き込み、最初のブロックをビットマップから利用可能なブロックに設定し、ビットマップのビットをトグルしてから、データを取得して正しいブロックに書き込みます。システムはこの情報をバッファリングするため、理想的には、ブロックがいっぱいになったときにブロックを 1 回だけ書き込む必要があります。
ブロックを書き込んでいる間、TOC からビットを消費し続け、ブロックを連鎖させます。
さらに、「ファイル コピー」は、ファイル システム コードとディスク ドライバを利用するシステムからの単純なプロセスです。ファイルのコピーは、バッファを読み込んで埋め、バッファを書き出すだけです。
ファイル システムは、すべてのメタ データを維持し、ファイルから読み取りを行っている場所、または書き込みを行っている場所を追跡する必要があります。たとえば、ファイルから 100 バイトだけを読み取る場合、明らかにシステムは 512 バイトのデータブロック全体を読み取る必要があり、ファイルから別の 100 バイトを読み取ろうとするときのために、それがバイト 101 にあることを「認識する」必要があります。
また、明らかだと思いますが、これは非常に粗雑なファイル システム レイアウトであり、多くの問題があります。
しかし、基本はそこにあり、すべてのファイル システムはこれに似た方法で動作しますが、詳細は大きく異なります (単純な例として、最近のほとんどのファイル システムにはハード リミットがありません)。
これは要求が厳しい、または非常に長い回答ですが、簡潔にしようとしています。
基本的に、.NET Framework は、いくつかの "ネイティブ" 呼び出し (下位レベルのライブラリで処理される呼び出し) をラップします。これらの低レベルの呼び出しは、多くの場合、ファイル コンテンツの同期などの複雑なことをユーザーから隠すために、バッファー ロジックにラップされます。
以下は、OS のカーネルと対話するネイティブ レベルです。次に、オペレーティング システムのコアであるカーネルが、高レベルの命令をハードウェアが理解できるものに変換します。たとえば、Windows と Linux はどちらもハードウェア アブストラクション レイヤーを使用しています。これは、ハードウェア固有の詳細を汎用インターフェイスの背後に隠すシステムです。特定のデバイス用のドライバーを作成することは、特定のデバイスが提供する必要があるすべてのメソッドを実装するタスクにすぎません。
ハードウェアで何かが呼び出される前に、ファイルシステムが関与し、ファイルシステム自体も多くのバッファリングとキャッシュを行いますが、これも透過的に行われるため、それに気付くことさえありません。call-queue の最後の要素はデバイス自体です。繰り返しますが、ほとんどのデバイスは何らかの標準 (SATA や IDE など) に準拠しているため、同様の方法でインターフェースできます。
これが役立つことを願っています:-)
.NET フレームワークは、Windows API を呼び出します。
Windows API には、さまざまなファイル システム間でファイルを管理するための関数があります。
次に、問題のファイルシステムによって異なります。これは必ずしも HDD 上の「通常の」ファイル システムではないことに注意してください。ドライブをエミュレートし、gmail アカウントなどにデータを保持するだけのシェル拡張機能でさえあります。要点は、Windows API の同じファイル操作関数が、考えられる多くのデータの下層に対する抽象化として使用されることです。
したがって、答えは、関心のあるファイルシステムの種類によって異なります。