2011-12-23 16 views
1

私はPOSIX specificationを読んでいます。ファイル記述子、ファイル記述、およびストリームがどのように相互作用するかを完全に理解することはできません。POSIXファイル記述子とCファイルの相互作用

FILE* f1 = fopen("a.txt", "r"); 
int fno = fileno(f1); 
FILE* f2 = fdopen(fno, "r"); 

// is it true? 
assert(fileno(f2) == fno); 

// does it close only f1 or f2 too? 
fclose(f1); 
fgetc(f2); // valid? 

は(質問はコメントである。)

答えて

4

C標準ライブラリを使用すると、不透明なポインタFILE*、あなたがfopen()/fclose()で操作できるファイルハンドル、およびfread()/fwrite()とのアクセスを提供します。

POSIXは、というファイルディスクリプタという概念を整数として提供しています。 open()/close()で操作でき、read()/write()でアクセスできます。

POSIXシステム上のすべてのオープンファイルハンドルFILE * fpに対して、fileno(fp)というファイルディスクリプタを取得できます。逆に、既存のファイル記述子nの場合は、標準ファイルハンドルをfdopen(n)で開くことができます。

つまり、POSIXファイル記述子は、には、C標準のioライブラリを実装するために使用されるオペレーティングシステムプリミティブです。 POSIXファイル記述子は、ソケットのハンドルとしても機能することに注意してください。

fclose()がファイルハンドルを無効にし、結果としてそのファイルディスクリプタを無効にするため、fgets()への最終呼び出しは未定義です。 fdopen()ではありません。ファイル記述子を複製します。

+0

私は各ファイル記述子で 'fdopen'を呼び出すことができます。 – ybungalobill

+1

ファイル記述子が他の 'FILE *'によっても使用されている場合は、2つの 'FILE * 'のうちの1つで確実に' fclose() 'を呼び出すことができるので、' fdopen() 'を一度でも確実に呼び出すことはできません。 ; 'fclose()'を確実に使用することはできません。 'fdopen()'を使う前に 'dup()'やおそらく 'dup2()'を使っていた場合は、ファイルディスクリプタを使い果たす前に 'fdopen()'を使うことができます。 –

+0

リソースを解放するだけでなく、私はバッファリングの混乱を予想していました。 –

1

はい、それは本当だと彼らは同じファイル記述子を使用するように、両方のファイルを閉じます。

+0

しかし、2番目の 'f2'がどのように解放されるのか(FILE構造)?私はもう 'fclose(f2)'と呼ぶことはできないと思いますよね? – ybungalobill

+0

まあ、分かりません;-)恐らく 'fdopen'は解放される新しい' FILE'オブジェクトを割り当てますが、それを閉じることは少し遅れます。私はあなたが 'fclose'を呼び出さなければならないと思いますが、失敗するかもしれません。同じディスクリプタを指し示すオブジェクトを 'FILE'する必要はありません。実際にそれが必要な場合は、ファイルハンドルを複製してください。 'fdopen(dup(fileno(f1))、..)のように' –

+0

'f2'は解放されません。代わりに、単に閉じられた古いファイル記述子が含まれています。 'f2'を使うとアプリケーションはクラッシュ(エラーを返します) - 同じファイル記述子で別のファイルを開いていないと仮定します。同じファイル上でStandard C IOとPOSIX IOを混在させてはいけません。それは悲惨さにつながります。 :) – sarnold

関連する問題