ISO C 표준에 명시, Unix System 이외의 여러 운영체제들에서도 구현됨.
SUS는 ISO C 표준에 대한 확장으로서 여러 추가적인 인터페이스 정의
5.2 Stream과 FILE 객체
파일을 생성하거나 열면 file stream을 얻게 됨. 이를 "stream을 file에 연관시켰다" 라고 함.
ASCII 문자 집합의 경우 하나의 문자는 하나의 byte로 표현됨.
국제 문자 집합의 경우 하나의 문자가 둘 이상의 byte로 표현됨.
스트림 지향(stream orientation) - 문자가 단일 byte로 접근되는지 다중 byte로 접근 되는지 결정
stream 처음 생성시 스트림에 지향이 없는 상태,
다중 byte I/O 함수(wchar.h)가 호출되면 스티림의 지향은 넓은 문자 지향(wide-oriented)이 됨.
단일 byte I/O 함수가 호출되면 스트림의 지향은 byte-oriented가 됨.
설정된 지향 변경 함수 : freopen(), fwide()
freopen() - stream 지향 삭제
fwide() - stream 지향 설정
#include <stdio.h>
#include <wschar.h>
int fwide(FILE *fp, int mode);
반환값 : 스트림이 넓은 문자 지향이면 양수, byte 지향이면 음수, 지향이 없으면 0
리눅스에서는 <libio.h> 헤더파일에 정의됨.
extern int _IO_fwide (_IO_FILE *__fp, int __mode) __THROW;
* mode 인수
1) 음수이면 fwide는 지정된 stream을 byte 지향으로 설정하려고 함.
2) 양수이면 fwide는 지정된 stream을 넓은 문자 지향으로 설정하려고 함.
3) 0이면 fwide는 지향을 설정하지 않고, 그냥 stream의 현재 지향을 뜻하는 값을 반환
지향이 이미 설정되어 있으면 fwide는 지향을 변경하지 않음.
* 유효하지 않은 stream이 주어진 경우
fwide를 호출하기 전에 errno를 초기화하고, 호출 반환후에 errno의 값을 점검함.
표준 I/O 함수 fopen으로 stream을 열면 FILE 객체를 가리키는 포인터를 반환함.
FILE 객체 - 표준 I/O 라이브러리가 stream을 관리하는데 필요한 모든 정보를 담은 구조체, 파일포인터라고도 부름
(File descriptor, buffer를 가리키는 포인터, buffer 크기, 현재 buffer에 들어가 있는 문자 개수, 오류 플래그등이 포함)
5.3 표준 I/O stream들 - 표준 입력, 표준 출력, 표준 오류
표준 파일 서술자 STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO와 동일한 파일들을 가리킴.
/* Standard streams. */
extern struct _IO_FILE *stdin; /* Standard input stream. */
extern struct _IO_FILE *stdout; /* Standard output stream. */
extern struct _IO_FILE *stderr; /* Standard error output stream. */
5.4 버퍼링
버퍼링의 목적은 read()과 write() call 횟수의 최소화
1) 전체 버퍼링
실제 I/O는 표준 I/O 버퍼가 꽉 찼을 때만 일어남. 디스크에 있는 파일들을 대상으로 적용됨.
해당 버퍼는 주어진 stream에 I/O가 처음 수행될 때, 표준 I/O 함수가 malloc을 호출해서 할당함.
방출(flush) - 표준 I/O 버퍼의 내용을 디스크에 기록하는 작업.
표준 I/O 루틴이 자동으로 방출(버퍼가 찼을 때), 프로그램의 fflush 호출에 의해 명시적으로 방출
2) line 버퍼링
표준 I/O 라이브러리는 입력이나 축력에서 새줄(newline)문자를 만났을때 I/O 수행
줄단위 버퍼링은 터미널을 가리키는 stream에 주로 쓰임. 표준 입력 스트림과 표준 출력 스트림에 사용됨.
주의점 2가지 :
A. 표준 I/O 라이브러리가 각 줄의 버퍼링에 사용하는 버퍼의 크기는 고정되어 있으며, 새줄(newline)문자가 나타가기 전에라도 버퍼가 꽉 차면 새줄 I/O가 수행됨.
B. 버퍼링 되지 않는 스트림이나 줄 단위 버퍼링 스트림으로부터의 입력이 요청되면, 줄 단위 버퍼링 출력 스트림들이 모두 방출됨
단, 줄 단위 버퍼링 스트림으로부터 입력이 요청된 경우는 자료를 커널이 요청했을 때만 해당
버퍼링 없는 stream에서는 모든 입력에 대해 커널이 자료를 읽어야 함
3) 버퍼링 없음
버퍼링하지 않음. 바로 출력됨.
표준 오류 스트림은 버퍼링되지 않음. 모든 오류 메시지가 새줄(newline) 포함 여부에 상관없이 즉시 표시됨.
* ISO C의 요구 사항
1) 표준 입력과 표준 출력은 전체 버퍼링이어야 함. 대화식 장치를 가리키는 경우는 제외
2) 표준 오류는 전체 버퍼링이 아님.
* 대부분의 UNIX 구현들의 버퍼링 사용 방식
1) 표준 오류는 항상 버퍼링되지 않음
2) 그 외의 stream들은 터미널 장치를 가리키는 경우에는 줄 단위 버퍼링이고, 그렇지 않으면 전체 버퍼링임.
stream의 버퍼링 방식 변경 함수 : setbuf(), setvbuf()
#include <stdio.h>
void setbuf(FILE *restrict fp, char *restrict buf);
int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);
반드시 stream을 연후, stream에 대해 다른 연산을 수행하기 전에 호출해야 함.
버퍼링을 킬 경우, 길이가 BUFSIZ(<stdio.h>에 정의됨)인 버퍼를 가리키는 포인터를 buf인수에 지정
버퍼링을 끌 경우, buf인수에 NULL 지정
* setvbuf() 함수의 mode 인수에 들어갈 값 :
1) _IOFBF(전체 버퍼링) - buf가 NULL 이면 표준 I/O 라이브러리가 지정된 stream에 대해 적절한 크기(상수 BUFSIZ에 정의된 값)를 직접 할당
2) _IOLBF(줄 단위 버퍼링) - buf가 NULL 이면 표준 I/O 라이브러리가 지정된 stream에 대해 적절한 크기(상수 BUFSIZ에 정의된 값)를 직접 할당
3) _IONBF(버퍼링 없음) - buf 인수와 size 인수가 무시됨
일부 C 라이브러리 구현들은 stat 구조체의 st_blksize 멤버의 값을 이용해서 최적의 표준 I/O 버퍼 크기 결정
* setbuf()와 setvbuf() 요약
함수
|
mode
|
buf
|
버퍼와 그 길이
|
버퍼링 종류
|
setbuf
|
null아님
|
사용자가 제공한 buf, 길이는 BUFSIZ
|
전체 버퍼링 또는 줄 단위 버퍼링
|
|
null
|
(버퍼없음)
|
버퍼링 없음
|
||
setvbuf
|
_IOLBF
|
null아님
|
사용자가 제공한 buf, 길이는 size
적절한 크기의 시스템 버퍼 |
전체 버퍼링
|
null
|
||||
_IOFBF
|
null아님
|
사용자가 제공한 buf, 길이는 size
적절한 크기의 시스템 버퍼 |
줄 단위 버퍼링
|
|
null
|
||||
_IONBF
|
무시됨
|
(버퍼 없음)
|
버퍼링 없음
|
함수내에 지역 변수로 buffer를 할당해 표준 I/O 버퍼로 지정한 경우
함수가 반환되기 전에 반드시 stream을 닫아야 함.
버퍼 크기와 할당을 자동으로 시스템이 하도록 맡겨야 하고, 그렇게 하면 stream이 닫힐 때 표준 I/O 라이브러리가 자동으로 버퍼를 해제함.
* fflush() : 버퍼 방출 용도, stream에 대해 아직 기록되지 않은 자료를 커널에 넘겨줌.
FILE 인자가 NULL일 경우 출력 stream들 전부가 방출됨
#include <stdio.h>
int fflush(FILE *fp)
반환값 : 성공시 0, 오류 시 EOF
5.5 Stream 열기
/* Open a file and create a new stream for it.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern FILE *fopen (__const char *__restrict __filename,
__const char *__restrict __modes);
/* Open a file, replacing an existing stream with it.
This function is a possible cancellation point and therefore not
marked with __THROW. */
extern FILE *freopen (__const char *__restrict __filename,
__const char *__restrict __modes,
FILE *__restrict __stream);
/* Create a new stream that refers to an existing system file descriptor. */
extern FILE *fdopen (int __fd, __const char *__modes) __THROW;
반환값 : 성공 시 파일 포인터, 오류시 NULL
fopen() - 지정된 파일 open 수행
freopen() - 지정된 파일을 지정된 stream으로 open 수행. 지정된 stream이 이미 열려 있으면 닫은 후 다시 open 수행.
stream에 지향이 설정되어 잇으면, freopen은 그 지향을 지움.
지정된 파일을 미리 정의된 stream들(표준 입력, 표준 출력, 표준 오류)중 하나로 open하는데 주로 쓰임.
fdopen() - 기존 file descriptor(open()이나 dup(), dup2(), fcntl(), pipe(), socket(), socketpair(), accept()로 얻은)를 받아서
표준 I/O stream과 연관시킴.
주로, 파이프나 네트워크 통신 채널을 생성하는 함수들이 돌려준 서술자를 스트림에 연관시키는 용도
fopen()과 freopen()은 ISO C의 일부임. fdopen()은 POSIX.1의 일부임.
ISO C는 File descriptor를 다루지 않음.
* 표준 I/O 스트림 열기에 쓰이는 type 인수의 값들
type
|
설명
|
r 또는
rb
|
읽기용으로 open
|
w 또는
wb
|
길이가 0이 되도록 자르거나 쓰기용으로 생성
|
a 또는
ab
|
추가, 즉 파일 끝에서 쓰도록 열거나 생성
|
r+ 또는
r+b 또는 rb+
|
읽기와 쓰기용으로 open
|
w+ 또는
w+b 또는 wb+
|
길이가 0이 되도록 자르거나 읽기,쓰기용으로
생성
|
a+ 또는
a+b 또는 ab+
|
파일의 끝에서 읽고 쓰도록 열거나 생성
|
댓글 없음:
댓글 쓰기