C fopen vs 오픈


219

당신이 사용하고 싶은 어떤 이유 (구문 적 이유가 아닌 것)가 있습니까?

FILE *fdopen(int fd, const char *mode);

또는

FILE *fopen(const char *path, const char *mode);

대신에

int open(const char *pathname, int flags, mode_t mode);

Linux 환경에서 C를 사용할 때?


이것을 찾으 셨나요? fdopen하고 openfopen하고 open?
user7116 2009

fdopen이 아니라 fopen을 의미합니까?
Omnifarious 2009

9
fopen표준 C 라이브러리의 일부입니다 open. fopen휴대용 코드를 작성할 때 사용하십시오 .
아지즈

그렇습니다. 방금 업데이트했지만 동일한 원칙이 적용됩니다.
LJM 2009

6
@Aziz open는 POSIX 함수입니다.
dreamlax 2009

답변:


242

첫째, fdopenif fopen가 옵션이고 open다른 가능한 선택 이라면 특별히 사용해야 할 이유가 없습니다 . open를 원한다면 처음에 파일을 여는 데 사용해서는 안됩니다 FILE *. 따라서 fdopen그 목록에 포함 시키는 것은 다른 것들과 크게 다르기 때문에 부정확하고 혼동됩니다. 여기서 중요한 차이점은 C 표준 FILE *과 OS 특정 파일 디스크립터 사이에 있기 때문에 무시하겠습니다 .

fopen대신에 4 가지 주요 이유가 있습니다 open.

  1. fopen는 버퍼링 IO를 제공하여 현재 수행하는 것보다 훨씬 빠를 수 있습니다 open.
  2. fopen 파일이 이진 모드로 열리지 않으면 줄 끝 변환을 수행합니다. 프로그램이 Unix 이외의 환경으로 이식 된 경우 세계가 LF 전용으로 수렴하는 것처럼 보이지만 (IETF 텍스트 기반 네트워킹 제외) SMTP 및 HTTP와 같은 프로토콜).
  3. A FILE *fscanf다른 stdio 기능 을 사용할 수있는 기능을 제공합니다 .
  4. 언젠가 코드는 ANSI C 만 지원하고 open기능을 지원하지 않는 다른 플랫폼으로 이식해야 할 수도 있습니다 .

제 생각에는 줄 끝 번역이 당신을 도와주는 것보다 더 자주 당신의 길을 가고 있습니다 fscanf.

그리고 C를 지원하는 대부분의 플랫폼에는 open기능이 있습니다.

그것은 버퍼링 질문을 남깁니다. 주로 파일을 순차적으로 읽거나 쓰는 곳에서 버퍼링 지원은 실제로 유용하고 속도가 크게 향상됩니다. 그러나 파일에 데이터가있을 것으로 예상 할 때 데이터가 파일에 포함되지 않는 흥미로운 문제가 발생할 수 있습니다. 당신을 기억해야 fclose또는 fflush적절한 시간에.

탐색을 수행하는 경우 (일명 fsetpos또는 fseek두 번째는 표준 호환 방식으로 사용하기가 약간 까다 로움) 버퍼링의 유용성이 빠르게 떨어집니다.

물론 내 편견은 소켓을 많이 사용하는 경향이 있으며, FILE *버퍼링 을 전혀 사용하지 않고 비 차단 IO ( 합리적으로 지원하지 못함)를 실제로하고 싶다는 사실이 있습니다. 복잡한 파싱 요구 사항이 실제로 내 인식을 채색합니다.


4
나는 당신의 경험에 의문을 제기하지 않을 것이지만, 당신이 이것에 대해 조금 자세히 설명하고 싶습니다. 어떤 종류의 응용 프로그램에 대해 내장 버퍼링이 방해가된다고 생각하십니까? 정확히 무엇이 문제입니까?
Emil H

1
마지막 단락을 보지 못했습니다. 유효 점, IMHO. 내가 알 수있는 한 파일 IO에 관한 것이 었습니다.
Emil H

7
버퍼링이 방해가되는 시점을 명확히하기 위해. 검색을 사용할 때입니다. 어떤 명령을 다음 읽기 ( fgets, fgetc, fscanf, fread), 항상 버퍼 (사용자가 설정 한 어떤 4K, 8K 또는)의 전체 크기를 읽습니다. 직접 I / O를 사용하면이를 피할 수 있습니다. 이 경우 pread검색 / 읽기 쌍 (2 대신 1 syscall) 대신 사용 하는 것이 더 좋습니다 .
Patrick Schlüter

2
중단 처리 read()write()호출하는 기능의 libc의 제품군을 사용하는 편리한 다섯 번째 이유입니다.
nccc

3
@ m-ric : 글쎄, 그것은 다소 관련이없는 질문이지만 그렇습니다. ioctl지원하는 모든 플랫폼 은 fileno통화를 지원하고 통화에 FILE *사용할 수있는 번호를 반환합니다 ioctl. 그래도 조심하십시오. FILE *관련된 호출은 ioctl기본 파일 디스크립터에 대해 무언가를 변경 하는 데 놀랍게 상호 작용할 수 있습니다 .
Omnifarious

53

open()저수준 OS 호출입니다. fdopen()os 레벨 파일 디스크립터를 C 언어의 상위 레벨 FILE-abstraction으로 변환합니다. 백그라운드에서 fopen()호출 open()하고 FILE 포인터를 직접 제공합니다.

원시 파일 디스크립터가 아닌 FILE 객체를 사용하면 몇 가지 장점이 있습니다. 여기에는 사용 편의성이 높지만 내장 버퍼링과 같은 다른 기술적 이점도 포함됩니다. 특히 버퍼링은 일반적으로 상당한 성능 이점을 제공합니다.


3
버퍼링 된 'f ...'버전의 오픈을 사용하는 데 단점이 있습니까?
LJM 2009

5
@엘. Moser, 예. 이미 데이터를 버퍼링 할 때 추가 버퍼로 인해 불필요한 복사 및 메모리 오버 헤드가 발생합니다.
Michael Aaron Safyan

6
실제로 다른 단점이 있습니다. fopen()파일을 열 때 동일한 권한 수준을 제공하지 않습니다 (예 : 권한 만들기, 공유 모드 등). 일반적으로 open()및 변형은 운영 체제가 실제로 제공하는 것에 근접하여 훨씬 더 많은 제어 기능을 제공합니다.
Matt Joiner

2
mmap파일이 있고 정상적인 I / O로 변경 하는 극단적 인 경우도 있습니다 (실제로 프로젝트에서 실제로 좋은 이유로 들리는 것처럼 놀라운 것처럼), 버퍼링은 방해가 될 것입니다.
Patrick Schlüter

readahead ()를 통해 파일을 페이지 캐시에 사전로드하기 위해 open () 사용과 같은 다른 시스템 기능을 사용할 수도 있습니다. 경험상 규칙은 "절대적으로 open ()이 필요하지 않으면 fopen 사용"이라고 생각합니다. open ()은 실제로 멋진 작업을 수행 할 수있게합니다 (O_ATIME 등을 설정 / 설정하지 않음).
Tomas Pruzina

34

fopen 대 C에서 열림

1) fopenA는 라이브러리 함수 상태 openA는 시스템 콜 .

2) fopen제공 버퍼 IO 빠른 비교되어 open있는은 비 버퍼 .

3) fopen휴대 하면서 open하지 포터블 ( 오픈 환경 특정 ).

4) FILE 구조 (FILE *)에fopen 대한 포인터를 반환합니다 . 파일을 식별하는 정수를 반환합니다. open

5) A FILE *fscanf 및 기타 stdio 기능 을 사용할 수있는 기능을 제공합니다 .


9
open는 POSIX 표준은 매우 휴대용, 그래서이다
osvein

12

사용 open이 실제 성능 이점 인 응용 프로그램의 0.1 %에 속하지 않는 한 실제로 사용하지 않는 좋은 이유는 없습니다 fopen. 멀리는 다음과 같이 fdopen우려는 파일 기술자와 함께 연주하지 않는 경우, 당신은 전화를 필요가 없습니다.

스틱 fopen및 방법의 제품군 ( fwrite, fread, fprintf, 등) 그리고 당신은 매우 만족됩니다. 마찬가지로 다른 프로그래머도 코드에 만족할 것입니다.


11

당신이있는 경우 FILE *, 당신은 같은 기능을 사용할 수 있습니다 fscanf, fprintf그리고 fgets당신은 그냥 파일 설명이있는 경우, 입력 및 출력 루틴 제한 (하지만 가능성이 더 빨리) 한 등 read, write


7

공개, 읽기, 쓰기를 사용하면 신호 혼입에 대해 걱정해야합니다.

신호 핸들러에 의해 호출이 중단 된 경우, 함수는 -1을 리턴하고 errno를 EINTR로 설정합니다.

따라서 파일을 닫는 올바른 방법은

while (retval = close(fd), retval == -1 && ernno == EINTR) ;

4
의 경우 close운영 체제에 따라 다릅니다. Linux, AIX 및 기타 운영 체제에서 루프를 수행하는 것은 올바르지 않습니다.
strcat

또한 읽기 및 쓰기를 사용하면 동일한 문제가 발생합니다. 즉, 입력 / 출력을 완전히 처리하기 전에 신호에 의해 중단 될 수 있으며 프로그래머는 이러한 상황을 처리해야하며, fread 및 fwrite는 신호 중단을 훌륭하게 처리해야합니다.
Marcelo

6

open()시스템 호출이며 Unix 기반 시스템에 고유하며 파일 디스크립터를 리턴합니다. write()다른 시스템 호출 인 파일 디스크립터에 쓸 수 있습니다 .
fopen()파일 포인터를 반환하는 ANSI C 함수 호출이며 다른 OS로 이식 가능합니다. 를 사용하여 파일 포인터에 쓸 수 있습니다 fprintf.

유닉스에서 : 다음을
사용하여 파일 디스크립터에서 파일 포인터를 얻을 수 있습니다.

fP = fdopen(fD, "a");

다음을 사용하여 파일 포인터에서 파일 설명자를 얻을 수 있습니다.

fD = fileno (fP);

4

open () 은 각 fopen () 패밀리 함수 의 끝에서 호출됩니다 . open () 은 시스템 호출이며 fopen () 은 라이브러리에서 사용자가 쉽게 사용할 수 있도록 래퍼 함수로 제공합니다.


2

fopen이 fopen fgetc을 실행할 때마다 fopen이 두 번 읽히기 때문에 fopen ()에서 open ()으로 변경했습니다. 이중 읽기는 내가 달성하려는 것을 방해했습니다. open ()은 당신이 요구하는 것을하는 것 같습니다.


2

어떤 플래그를 열어야하는지에 따라 다릅니다. 쓰기 및 읽기 사용 (및 이식성)과 관련하여 위에서 언급 한 것처럼 f *를 사용해야합니다.

그러나 기본적으로 rw 및 append 플래그와 같은 표준 플래그보다 더 많은 플래그를 지정하려면 POSIX open과 같은 플랫폼 특정 API 또는 이러한 세부 정보를 추상화하는 라이브러리를 사용해야합니다. C 표준에는 이러한 플래그가 없습니다.

예를 들어 파일이 종료 된 경우에만 파일을 열 수 있습니다. 작성 플래그를 지정하지 않으면 파일이 존재해야합니다. 작성 전용을 추가하면 파일이 존재하지 않는 경우에만 파일이 작성됩니다. 더 많은 것이 있습니다.

예를 들어 Linux 시스템에는 sysfs를 통해 노출 된 LED 인터페이스가 있습니다. 파일을 통해 LED의 밝기를 노출시킵니다. 0-255 범위의 문자열로 숫자를 쓰거나 읽습니다. 물론 해당 파일을 작성하지 않고 존재하는 경우에만 쓰십시오. 멋진 점 : fdopen을 사용하여 표준 호출을 사용하여이 파일을 읽거나 씁니다.


0

디스크의 파일에서 정보를 읽거나 쓰기 위해 fopen
을 사용하여 파일을 열려면 파일을 열어야합니다. 파일을 열려면 fopen 함수를 호출했습니다.

1.firstly it searches on the disk the file to be opened.
2.then it loads the file from the disk into a place in memory called buffer.
3.it sets up a character pointer that points to the first character of the buffer.

fopen 함수 의 동작 방식은
버퍼링 프로세스 중에 일부 원인이 있으며 시간 초과 될 수 있습니다. 그래서 비교하는 동안 fopen의 (높은 수준의 I / O)하는 시스템 호출 (I / O를 로우 레벨), 그리고 빠르고보다 적절한 는 fopen .


fopen보다 더 빨리 열려 있습니까?
obayhan

네, 오픈 comparitively @obayhan - 빠른 fopen을보다 시스템 호출입니다
prashad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.