글쎄요... 전 Turbo C 2.0부터 사용해 보았습니다만, DOS에서도 open/close 함수를 사용했습니다. 게다가 지금도 Visual C++ 런타임으로 _open/_close 함수가 있습니다. 앞에 underline이 들어가 있긴 하지만 유닉스의 open/close와 똑같은 기능을 할 겁니다.
struct __FILE_TAG /* needs to be binary-compatible with old versions */
{
#ifdef _STDIO_REVERSE
unsigned char *_ptr; /* next character from/to here in buffer */
ssize_t _cnt; /* number of available characters in buffer */
#else
ssize_t _cnt; /* number of available characters in buffer */
unsigned char *_ptr; /* next character from/to here in buffer */
#endif
unsigned char *_base; /* the buffer */
unsigned char _flag; /* the state of the stream */
unsigned char _file; /* UNIX System file descriptor */
unsigned __orientation:2; /* the orientation of the stream */
unsigned __ionolock:1; /* turn off implicit locking */
unsigned __filler:5;
};
_file 이라는 필드가 unsigned char 로 되어 있는 것을 보실 수 있습니다.
(Solaris 7, Solaris 8기준. Solaris 2.6도 unsigned char 였던 것으로 기억합니다.)
따라서 이 녀석이 가리킬 수 있는 파일디스크립터가 256개 밖에 안되기 때문에 일어나는 일입니다.
아마 제 기억으로는 256번 이상 불려도 fopen()이 실패하지는 않았던 것 같은데 mod 256 이 되니까 원했던 파일이 아니라 다른 파일을 가리켰던 것 같습니다만, 확인해 봐야겠네요.
참고로 AIX(4.3.3)와 Tru64(5.1) 는 short _file; 로 디스크립터를 표현하고 있고, HP-UX (11.0)은 unsigned char __fileL; unsigned char __fileH; 로 나누어서 표현하네요.
3) What is the difference between open(),read(), write(), close(), etc. and fopen(), fread(), fwrite(), fclose(), etc.?
Answer: The first group are the Unix system calls for I/O which are direct entry points into the kernel. They can be used not only for files but also for IPC channels (such as PIPE, FIFO) and Sockets. The second group are the standard I/O library functions, providing a higher level interface between a process and the kernel with features such as buffering, line-by-line input, formatted output, and the like. The second group will be finally implemented with the first group. With network programming, however, there are times when the Unix system calls must be used.
open은 system call이고 fopen은 c언어에서 지원하는 함수일겁니다.
fopen은 독자적인 버퍼를 이용해서 파일을 열고 open은
system 버퍼를 이용해서 연다고.. 그 차이인것 같습니다.
fopen()은 라이브러리이고 라이브러리 수준에서 버퍼링을 수행합니다. 그러나, 결국 운영체제를 거쳐야 IO를 수행할 수 있고, open()을 호출할 수 밖에는 없습니다. open()은 운영체제로의 파일액세스를 위한 창구입니다. 버퍼링 및 포맷팅등의 코딩이 귀찮아서 fopen을 비롯한 fxxxx()시리즈를 사용하는 것은 어쩔 수 없다지만, 저는 개인적으로 지금까지 이를 사용하는것에 반대해왔고, 현재도 그러합니다. 가급적 버퍼는 프로그래머의 원천코드로 직접관리하는게 옳다고 생각합니다.
자세히는 모르지만...
저도 잘아는 편이 아니라 정확하게는 말씀못드리지만
(고수분들이 틀리면 지적해주시겠죠.)
open은 system call이고 fopen은 c언어에서 지원하는 함수일겁니다.
fopen은 독자적인 버퍼를 이용해서 파일을 열고 open은
system 버퍼를 이용해서 연다고.. 그 차이인것 같습니다.
음... fopen은 open의 wrapper함수 아닌가요? wrappe
음... fopen은 open의 wrapper함수 아닌가요? wrapper라고 표현하는게 맞는지 모르겠는데...
open은 파일 디스크립터를 되돌려주는데 fopen은 내부에서 open을 호출하고 그 파일 디스크립터와 파일 스트림을 위한 버퍼 등등으로 구조체를 할당해 되돌려 주는 걸로 알고 있습니다.
즉 fopen은 open에 비해 추가적인 메모리를 더 필요로 하기 때문에 그런게 아닐까 싶네요...
노루가 사냥꾼의 손에서 벗어나는 것 같이, 새가 그물치는 자의 손에서 벗어나는 것 같이 스스로 구원하라 -잠언 6:5
그건..
제 생각으로는 fopen, open의 차이가 아니라고 생각됩니다.
fopen으로 열어도 시스템의 최대치 만큼 열수 있습니다..
파일 디스크립터는 fopen 과 open의 차이가 실제로 없습니다.
무언가 다른 부분에서 잘못 되서 그런것 같습니다..
fopen 과 open 은
libio.h 헤더파일을 다들 아시겠지만
fopen에 쓰이는 FILE구조체는 _IO_FILE로서 멤버로 file descriptor를
갖고있습니다. 따라서 fileno() 와 같은 함수로 FILE 구조체와 fd 간에
변환도 가능하구요.
따라서 제가 알기로는 ulimit 에서 지정된 파일열기제한값만큼의 파일을
오픈할수 있는 것으로 알고 있습니다. 동일프로세스 내에서 256개밖에
열수없었다는 것은 무엇인가 다른 요인이 있을 것입니다. 만일 그렇다면
시스템호출이냐 아니냐의 차이가 원인일수도 있습니다.
플랫폼에 따라서는 내부적 구현이 둘다 유사하게 돌아가기도 합니다.
일례로 AIX상의 aiocb 구조체를 보면(대형시스템에서는 시스템콜로써
asynchronous i/o가 구현됩니다) 멤버에 FILE 구조체가 포함되는
것을 볼수 있습니다. (시스템콜이 FILE구조체를 참조합니다)
homeless
쩝
제가 보기엔 fopen은 C언어 표준 라이브러리고요
open은 유닉스 전용함수입니다
내부적으로는 fopen을 open으로 구현했을거라 보이네요
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
ISO C Standard에서 fopen으로 동시에 열 수 있는 파일의
ISO C Standard에서 fopen으로 동시에 열 수 있는 파일의 갯수는 FOPEN_MAX로 정의하고 있습니다. (<stdio.h>) 참고하시길..
mastercho님이 말씀하신 것처럼, fopen(3)은 ISO C Standard library function이고, open(2)는 POSIX.1 표준 함수입니다.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
Re: 쩝
글쎄요... 전 Turbo C 2.0부터 사용해 보았습니다만, DOS에서도 open/close 함수를 사용했습니다. 게다가 지금도 Visual C++ 런타임으로 _open/_close 함수가 있습니다. 앞에 underline이 들어가 있긴 하지만 유닉스의 open/close와 똑같은 기능을 할 겁니다.
-----
http://monpetit.posterous.com/
http://monpetit.tistory.com/
Solaris 쪽의 FILE 구조체 선언을 쫓아가 보시면[co
Solaris 쪽의 FILE 구조체 선언을 쫓아가 보시면
_file 이라는 필드가 unsigned char 로 되어 있는 것을 보실 수 있습니다.
(Solaris 7, Solaris 8기준. Solaris 2.6도 unsigned char 였던 것으로 기억합니다.)
따라서 이 녀석이 가리킬 수 있는 파일디스크립터가 256개 밖에 안되기 때문에 일어나는 일입니다.
아마 제 기억으로는 256번 이상 불려도 fopen()이 실패하지는 않았던 것 같은데 mod 256 이 되니까 원했던 파일이 아니라 다른 파일을 가리켰던 것 같습니다만, 확인해 봐야겠네요.
참고로 AIX(4.3.3)와 Tru64(5.1) 는 short _file; 로 디스크립터를 표현하고 있고, HP-UX (11.0)은 unsigned char __fileL; unsigned char __fileH; 로 나누어서 표현하네요.
조금 전에 찾은 관련 문서입니다. 참고하세요.http://www.ec
조금 전에 찾은 관련 문서입니다. 참고하세요.
http://www.ece.eng.wayne.edu/~gchen/ece5650/faq.htm#_3)_What_is
-----
http://monpetit.posterous.com/
http://monpetit.tistory.com/
Re: 자세히는 모르지만...
fopen()은 라이브러리이고 라이브러리 수준에서 버퍼링을 수행합니다. 그러나, 결국 운영체제를 거쳐야 IO를 수행할 수 있고, open()을 호출할 수 밖에는 없습니다. open()은 운영체제로의 파일액세스를 위한 창구입니다. 버퍼링 및 포맷팅등의 코딩이 귀찮아서 fopen을 비롯한 fxxxx()시리즈를 사용하는 것은 어쩔 수 없다지만, 저는 개인적으로 지금까지 이를 사용하는것에 반대해왔고, 현재도 그러합니다. 가급적 버퍼는 프로그래머의 원천코드로 직접관리하는게 옳다고 생각합니다.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
댓글 달기