7

私はかなり長い間Cから離れていた後、Cで小さなプロジェクトを行っています。これらには、たまたまファイル処理が含まれています。FILE *さまざまなドキュメントで、ハンドルを返す関数と (小さな整数) 記述子を返す関数があることに気付きました。どちらの機能セットも必要な基本サービスは同じなので、どちらを使用してもかまいません。

しかし、私はコレクションの知恵に興味があります: fopen()and friends と and friends のどちらを使うのが良いopen()でしょうか?

編集誰かがバッファありとバッファなし、およびデバイスへのアクセスについて言及したので、この小さなプロジェクトの一部が FUSE の下でユーザー空間ファイルシステム ドライバーを作成することを追加する必要があります。したがって、ファイル レベルのアクセスは、デバイス (CDROM や SCSI ドライブなど) に対しても、"ファイル" (つまり、イメージ) に対しても簡単に行うことができます。

4

7 に答える 7

3

はい。低レベルのハンドルが必要な場合。

UNIX オペレーティング システムでは、通常、ファイル ハンドルとソケットを交換できます。

また、低レベルのハンドルは、FILE ポインターよりも ABI との互換性が高くなります。

于 2009-02-13T04:08:31.650 に答える
2

read() & write() はバッファリングされていない I/O を使用します。( fd : 整数ファイル記述子)

fread()fwrite() はバッファリングされた I/O を使用します。( FILE *構造体ポインタ)

write() を使用してパイプに書き込まれたバイナリ データは、バイト アラインメントや変数のサイズなどにより、fread()を使用してバイナリ データを読み取ることができない場合があります。

低レベルのデバイス ドライバー コードのほとんどは、バッファーなしの I/O 呼び出しを使用します。

ほとんどのアプリケーション レベルの I/O はバッファリングを使用します。

FILE * とそれに関連する関数の使用は、マシンごとに問題ありません。ただし、バイナリ データの読み取りと書き込みにおいて、他のアーキテクチャでは移植性が失われます。fwrite() はバッファリングされた I/O であり、64 ビット アーキテクチャ用に記述して 32 ビットで実行すると、信頼できない結果になる可能性があります。または (Windows/Linux)。ほとんどの OS には、これを防ぐために独自のコード内に互換性マクロがあります。

低レベルのバイナリ I/O の移植性のために、 read()write()は、異なるアーキテクチャでコンパイルされたときに、同じバイナリの読み取りと書き込みを保証します。基本的なことは、どちらかの方法を選択し、バイナリ スイート全体で一貫性を保つことです。

<stdio.h>  // mostly FILE*  some fd input/output parameters for compatibility
             // gives you a lot of helper functions -->
List of Functions
       Function      Description
       ───────────────────────────────────────────────────────────────────
       clearerr      check and reset stream status
       fclose        close a stream
       fdopen        stream open functions //( fd argument, returns FILE*)                      feof          check and reset stream status
       ferror        check and reset stream status
       fflush        flush a stream
       fgetc         get next character or word from input stream
       fgetpos       reposition a stream
       fgets         get a line from a stream
       fileno        get file descriptor   // (FILE* argument, returns fd) 
       fopen         stream open functions
       fprintf       formatted output conversion
       fpurge        flush a stream
       fputc         output a character or word to a stream
       fputs         output a line to a stream
       fread         binary stream input/output
       freopen       stream open functions
       fscanf        input format conversion
       fseek         reposition a stream
       fsetpos       reposition a stream
       ftell         reposition a stream
       fwrite        binary stream input/output
       getc          get next character or word from input stream
       getchar       get next character or word from input stream
       gets          get a line from a stream
       getw          get next character or word from input stream
       mktemp        make temporary filename (unique)
       perror        system error messages
       printf        formatted output conversion
       putc          output a character or word to a stream
       putchar       output a character or word to a stream
       puts          output a line to a stream
       putw          output a character or word to a stream
       remove        remove directory entry
       rewind        reposition a stream
       scanf         input format conversion
       setbuf        stream buffering operations
       setbuffer     stream buffering operations
       setlinebuf    stream buffering operations
       setvbuf       stream buffering operations
       sprintf       formatted output conversion
       sscanf        input format conversion
       strerror      system error messages
       sys_errlist   system error messages
       sys_nerr      system error messages
       tempnam       temporary file routines
       tmpfile       temporary file routines
       tmpnam        temporary file routines
       ungetc        un-get character from input stream
       vfprintf      formatted output conversion
       vfscanf       input format conversion
       vprintf       formatted output conversion
       vscanf        input format conversion
       vsprintf      formatted output conversion
       vsscanf       input format conversion

したがって、基本的な使用では、イディオムをあまり混ぜずに上記を個人的に使用します。

対照的に、

<unistd.h>   write()
             lseek()
             close()
             pipe()
<sys/types.h>
<sys/stat.h>
<fcntl.h>  open()
           creat()
           fcntl() 
all use file descriptors.

これらは、バイトの読み取りと書き込みをきめ細かく制御します (特殊なデバイスと fifo (パイプ) に推奨)。

繰り返しますが、必要なものを使用しますが、イディオムとインターフェイスの一貫性を保ちます。ほとんどのコード ベースで 1 つの mode を使用している場合は、そうしない本当の理由がない限り、それも使用してください。I/O ライブラリ関数の両方のセットは非常に信頼性が高く、1 日に何百万回も使用されています。

注 -- CI/O を別の言語 (perl、python、java、c#、lua など)と接続している場合は、C コードを作成する前に、それらの言語の開発者が推奨するものを調べて、トラブルを回避してください。

于 2012-06-03T21:40:36.580 に答える
2

通常、標準ライブラリ (fopen) を使用することをお勧めします。ただし、 open を直接使用する必要がある場合もあります。

頭に浮かぶ 1 つの例は、solaris の古いバージョンで、256 個のファイルが開かれた後に fopen が失敗するバグを回避することです。これは、彼らが int の代わりに struct FILE 実装の fd フィールドに誤って unsigned char を使用したためです。しかし、これは非常に特殊なケースでした。

于 2009-02-13T04:07:30.263 に答える
0

fopen とそのいとこはバッファリングされます。open、read、および write はバッファリングされません。あなたのアプリケーションは気にするかもしれませんし、気にしないかもしれません。

fprintf と scanf には、書式設定されたテキスト ファイルを読み書きできる豊富な API があります。読み取りと書き込みは、バイトの基本配列を使用します。変換と書式設定は手作業で行う必要があります。

ファイル記述子と (FILE *) の違いは、実際には重要ではありません。

ランディ

于 2009-02-13T04:58:03.433 に答える