파일 설명자와 파일 포인터의 차이점은 무엇입니까?


답변:


144

파일 디스크립터는 Linux 및 기타 유닉스 계열 시스템에서 커널 수준에서 열린 파일 (또는 소켓 등)을 식별하는 데 사용되는 저수준 정수 "핸들"입니다.

당신은 같은 실제 유닉스 호출에 "알몸"파일 설명을 통과 read(), write()등등.

FILE포인터는 파일을 표현하는 데 사용되는 C 표준 라이브러리 수준의 구조입니다. 는 FILE파일 기술자를 래핑, 그리고 I / O를 쉽게하기 위해 버퍼링 및 기타 기능을 추가합니다.

당신은 통과 FILE같은 표준 C 함수에 대한 포인터를 fread()하고 fwrite().


@nvl : fildes는 Windows에서 확실히 사용할 수 있습니다. 예 : msdn.microsoft.com/en-us/library/z0kc8e3z%28VS.80%29.aspx
kennytm

2
@unwind "네이 키드"파일 설명 자란 무엇을 의미합니까? 링크 된 참조는가 fd에 대한 첫 번째 인수 라고 말합니다 read(). 왜 알몸이라고 부르나요?
Geek

3
@Geek 표준 라이브러리의 FILE *유형과 비교할 때 정수 파일 설명자는 "덜 래핑"됩니다. 즉 "naked"입니다.
긴장 풀기

57

하나는 버퍼링되고 ( FILE *) 다른 하나는 버퍼링 되지 않습니다. 실제로, 당신은 FILE *당신이 무엇을하고 있는지 또는 당신의 파일이 실제로 소켓이 아닌 경우가 아니라면, 당신이 '실제'파일 (즉, 드라이브에서)에서 읽을 때 거의 항상 사용하기를 원합니다 .

FILE *사용 에서 파일 설명자를 가져올 수 있으며 다음을 사용하여 파일 설명자에서 fileno()버퍼링 된 FILE *파일을 열 수 있습니다.fdopen()


12
fileno ()를 지적하기 위해 +1, man 페이지의 구성은 이것을 찾기 어렵게 만듭니다. fdopen ()과 동일합니다.
BD at Rivenhill 2010

20

파일 설명자는 POSIX open()호출 에서 얻은 정수일뿐입니다 . 표준 C fopen()를 사용하면 FILE구조체를 다시 얻을 수 있습니다. FILE구조체는 파일의 끝 등의 에러 표시, 스트림 위치와 같은 다른 것들 사이에이 파일 디스크립터를 포함

따라서를 사용 fopen()하면 open(). 일반적으로 fopen()더 이식성이 FILE높고 struct, ie fprintf()및 family 를 사용하는 다른 모든 표준 C 함수를 사용할 수 있기 때문에 사용해야합니다 .

둘 중 하나를 사용하면 성능 문제가 없습니다.


8
휴대 성을 높이기 위해 +1. FILE은 표준 C 라이브러리의 일부입니다 (C89 / C90으로 돌아 가기). 파일 설명자는 그렇지 않습니다.
tomlogic 2010 년

15

파일 설명자 대 파일 포인터

파일 설명자 :

파일 설명자는 open()시스템 호출에서 반환 된 정수 값 입니다.

int fd = open (filePath, mode);

  1. 로우 / 커널 레벨 핸들러.
  2. UNIX 시스템 호출의 read () 및 write ()에 전달합니다.
  3. 버퍼링 및 이러한 기능은 포함되지 않습니다.
  4. 휴대 성이 떨어지고 효율성이 떨어집니다.

파일 포인터 :

파일 포인터는 파일 식별, 파일 설명자 래핑, 버퍼링 기능 및 I / O 작업에 필요한 기타 모든 기능에fopen() 사용 되는 라이브러리 함수에 의해 반환 된 C 구조에 대한 포인터입니다. 파일 포인터는 FILE 형식 이며 해당 정의는 "/usr/include/stdio.h" 에서 찾을 수 있습니다 . 이 정의는 컴파일러마다 다를 수 있습니다.

FILE *fp = fopen (filePath, mode);

// A FILE Structure returned by fopen 
    typedef struct 
    {
        unsigned char   *_ptr;
        int     _cnt;
        unsigned char   *_base;
        unsigned char   *_bufendp;
        short   _flag;
        short   _file;
        int     __stdioid;
        char    *__newbase;
#ifdef _THREAD_SAFE
        void *_lock;
#else
        long    _unused[1];
#endif
#ifdef __64BIT__
        long    _unused1[4];
#endif /* __64BIT__ */
    } FILE;
  1. 높은 수준의 인터페이스입니다.
  2. fread () 및 fwrite () 함수에 전달됩니다.
  3. 버퍼링, 오류 표시 및 EOF 감지 등이 포함됩니다.
  4. 더 높은 이동성과 효율성을 제공합니다.

1
더 높은 효율성 주장을 뒷받침 할 수 있습니까? 나는 들어 본 적이 없다.
Gid

1
"효율성"주장은 버퍼링 때문일 수 있습니다. 파일 디스크립터를 사용하면 모든 read () 또는 write ()는 syscall이며 모든 syscall은 비용이 많이 드는 것으로 간주되어야합니다. FILE *에서 버퍼링은 일부 읽기 및 쓰기가 syscall이 아님을 의미합니다.
Mike Spear

12

유용 할 수있는 포인트를 추가하고 싶습니다.

FILE *

  1. 프로세스 간 통신 (IPC)에는 사용할 수 없습니다.
  2. 범용 버퍼링 된 I / O가 필요할 때 사용하십시오. (printf, frpintf, snprintf, scanf)
  3. 디버그 로그에 여러 번 사용합니다. 예,

                 FILE *fp;
                 fp = fopen("debug.txt","a");
                 fprintf(fp,"I have reached till this point");
                 fclose(fp);

FILE DESCRIPTOR

  1. 일반적으로 IPC에 사용됩니다.

  2. * nix 시스템의 파일 (장치, 파일, 소켓 등)에 대한 저수준 제어를 제공하므로 FILE *.


fdopen()IPC 및 장치와 같은 작업을 수행 하는 데 사용할 수 없습니까 FILE*?
osvein

사실, 그렇기도하고 아니기도합니다. IPC를 설정하고 초기화 할 수 없습니다.FILE* 할 수는 없지만 FILE*파일 설명자 ( fdopen()) 에서를 만들 수 있으며 나중에을 닫으면 FILE설명 자도 닫힙니다. 따라서 IPC 를 수행 할 수 있지만 직접 IPC를 용이하게하려면 파일 설명자를 약간 다루어야합니다.
Micah W

3

FILE * 텍스트 파일 및 사용자 입력 / 출력으로 작업 할 때 더 유용합니다. 왜냐하면 다음과 같은 API 함수를 사용할 수 있기 때문입니다. sprintf() , sscanf(), fgets(), feof()

파일 설명자 API는 저수준이므로 소켓, 파이프, 메모리 매핑 된 파일 (물론 일반 파일)과 함께 작업 할 수 있습니다.


1
+1 메모리 매핑 파일을 추가했기 때문에 현재 읽고있는 현재 다른 답변이 이미 제공 되었기 때문입니다.
ernie.cordell 2014

3

토론을 완료하기위한 메모 (관심있는 경우) ....

fopen안전하지 않을 수 있으며 fopen_s또는 open독점 비트 세트를 사용해야 합니다. C1X는 x모드 를 제공 하므로 모드를 사용할 수 fopen있습니다 "rx"."wx" 등,

당신이 사용하는 경우 open, 당신은 고려해 볼 수 있습니다 open(..., O_EXCL | O_RDONLY,... )또는open(..., O_CREAT | O_EXCL | O_WRONLY,... ) .

예를 들어 fopen () 및 파일 생성에 대해 가정하지 마십시오 .


으로 fopen_s사용할 수하지 않는 것 POSIX, 나는 대부분의 휴대용 soultion가 될 것이라고 가정 open(2)하고 fdopen(2). (창문을 제쳐두고). 또한 더 빠르 fopen_s()거나 open(2)뒤 따르는 것은 fdopen(2)무엇입니까?
Mihir

1

시스템 호출은 대부분 파일 설명자를 사용합니다 (예 : readwrite. 라이브러리 함수는 파일 포인터 ( printf, scanf)를 사용합니다. 그러나 라이브러리 함수는 내부적으로 시스템 호출 만 사용합니다.


라이브러리 함수가 내부 시스템 호출 만 사용한다고 말하는 이유를 잘 모르겠습니다. 표준 CI / O (또는 해당 문제에 대한 다른 기능) 기능을 의미한다면 그게 (보편적으로?) 사실인지 잘 모르겠습니다. 그렇지 않으면, 당신이 말한 것이 아니므로 당신의 게시물에서 언어가 약간 정리되는 것을보고 싶습니다. 마지막 문장은 나를 당황하게한다.
ernie.cordell 2014

1

여기서 좋은 리소스를 찾았 으며 둘 사이의 차이점에 대한 높은 수준의 개요를 제공합니다.

파일에 대한 입력 또는 출력을 수행하려는 경우 프로그램과 파일 간의 연결을 나타내는 두 가지 기본 메커니즘 인 파일 설명자 및 스트림을 선택할 수 있습니다. 파일 설명자는 int 유형의 객체로 표현되는 반면 스트림은 FILE * 객체로 표현됩니다.

파일 설명자는 입력 및 출력 작업에 대한 기본 저수준 인터페이스를 제공합니다. 파일 설명자와 스트림은 모두 장치 (예 : 터미널)에 대한 연결 또는 다른 프로세스와 통신하기위한 파이프 또는 소켓 및 일반 파일을 나타낼 수 있습니다. 그러나 특정 종류의 장치에 특정한 제어 작업을 수행하려면 파일 설명자를 사용해야합니다. 이런 식으로 스트림을 사용할 수있는 기능이 없습니다. 프로그램이 비 블로킹 (또는 폴링) 입력과 같은 특수 모드에서 입력 또는 출력을 수행해야하는 경우에도 파일 설명자를 사용해야합니다 (파일 상태 플래그 참조).

스트림은 원시 파일 설명자 기능 위에 계층화 된 상위 레벨 인터페이스를 제공합니다. 스트림 인터페이스는 모든 종류의 파일을 거의 비슷하게 처리합니다. 유일한 예외는 선택할 수있는 세 가지 버퍼링 스타일입니다 (스트림 버퍼링 참조).

스트림 인터페이스 사용의 주요 이점은 스트림에서 실제 입력 및 출력 작업을 수행하는 기능 세트 (제어 작업과 반대)가 파일 설명자에 해당하는 기능보다 훨씬 풍부하고 강력하다는 것입니다. 파일 설명자 인터페이스는 문자 블록을 전송하기위한 간단한 기능 만 제공하지만 스트림 인터페이스는 또한 강력한 형식의 입력 및 출력 함수 (printf 및 scanf)와 문자 및 행 지향 입력 및 출력을위한 기능을 제공합니다.

스트림은 파일 설명자 측면에서 구현되므로 스트림에서 파일 설명자를 추출하고 파일 설명자에서 직접 저수준 작업을 수행 할 수 있습니다. 처음에 연결을 파일 설명 자로 연 다음 해당 파일 설명자와 관련된 스트림을 만들 수도 있습니다.

일반적으로 파일 디스크립터에서만 수행 할 수있는 특정 작업을 수행하려는 경우가 아니라면 파일 디스크립터보다는 스트림 사용을 고수해야합니다. 초보 프로그래머이고 어떤 함수를 사용해야할지 잘 모르겠다면 형식화 된 입력 함수 (형식화 된 입력 참조) 및 형식화 된 출력 함수 (형식화 된 출력 참조)에 집중하는 것이 좋습니다.

GNU가 아닌 다른 시스템으로의 프로그램 이식성에 대해 염려한다면 파일 설명자가 스트림만큼 이식 가능하지 않다는 점도 알아야합니다. ISO C를 실행하는 모든 시스템이 스트림을 지원할 것으로 예상 할 수 있지만 GNU가 아닌 시스템은 파일 설명자를 전혀 지원하지 않거나 파일 설명자에서 작동하는 GNU 함수의 하위 집합 만 구현할 수 있습니다. 그러나 GNU C 라이브러리에있는 대부분의 파일 설명자 함수는 POSIX.1 표준에 포함되어 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.