0

ディスクファイルの場合のように、可能な場合に真のファイル記述子クローンメカニズムがないのはなぜですか。

POSIX:

これらのシステム コールの 1 つから正常に戻った後、古いファイル記述子と新しいファイル記述子を交換可能に使用できます。これらは同じオープン ファイル記述 (open(2) を参照) を参照するため、ファイル オフセットとファイル ステータス フラグを共有します。たとえば、記述子の 1 つで lseek(2) を使用してファイル オフセットを変更すると、もう一方のオフセットも変更されます。

ウィンドウズ:

複製ハンドルは、元のハンドルと同じオブジェクトを参照します。したがって、オブジェクトへの変更は両方のハンドルを介して反映されます。たとえば、ファイル ハンドルを複製した場合、現在のファイル位置は両方のハンドルで常に同じになります。ファイル ハンドルが異なるファイル位置を持つようにするには、CreateFile 関数を使用して、同じファイルへのアクセスを共有するファイル ハンドルを作成します。

クローン プリミティブを使用する理由:

  • ファイル アーカイブを操作する場合、アーカイブ内の各ファイルに個別にアクセスできる必要があります。ファイル アーカイブは、仮想ファイル システムのように動作する必要があります。

  • ファイルタイプのチェック。ファイル オフセットのクローンを作成できるため、元の位置に影響を与えることなく、ファイルのごく一部を読み取ることができます。

4

1 に答える 1

0

次のことを考慮する必要があります。ファイル記述子は、カーネル側の「ファイル」(文字通り、それが呼ばれるもの) オブジェクト ポインターの配列への単なるオフセットです。したがって、ファイル記述子を複製すると、カーネルは単にファイル ポインターの値を配列内のある場所から別の場所にコピーし、ポイントされたオブジェクトの参照カウントを増やします。

したがって、問題はファイル記述子の複製ではなく、ファイル オフセットの管理にあります。これに対する簡単な答えは、自分で行うことです。つまり、現在のファイル オフセットをアプリケーション側の各ファイル記述子に明示的に関連付けます。

もちろん、最も基本的なファイル アクセス システムは、カーネルが保持するファイル オフセット変数を呼び出しread()て、write()利用できる場合は利用します (「通常の」ランダム アクセス ファイルを扱っている場合にのみ利用できます)。しかし、より高度なファイル アクセス システム コールでは、呼び出しのたびに、目的のファイル オフセットがアプリケーションによって提供されることが期待されます。それらにはpread()/ pwrite()preadv()/ pwritev()、およびaio_read()/が含まれますaio_write(後者はおそらく、あなたが説明したような並列アクセス アプリケーションを作成するための最良のアプローチです)。

Windows では、ReadFile()/ WriteFile()ReadFileScatter()/ WriteFileGather()、およびReadFileEx()/は同様に、すべての呼び出しで (引数WriteFileEx()を介して) ファイル オフセットが渡されることを期待しています。lpOverlapped

于 2014-12-05T08:11:16.830 に答える