stdio: Standard I/O Library
- Perfomance issues
- Alignment
- I/O performance is optimal when requests are issued on block-aligned boundaries in integer multiples of the block size
- I/O의 성능은 OS가 관리하는 block사이즈의 배수로 관리되는 buffer의 유무에 달려있습니다. 즉 buffer의 시작주소나 길이가 block size의 양수배여야 성능이 좋아집니다.
- Number of system calls
- Performance degradation is exacerbated by the increased number of system calls required to read
- A single byte 1,024 times rather than 1,024 bytes all at once
- system call의 횟수가 매우 중요합니다.
- Performance degradation is exacerbated by the increased number of system calls required to read
- Alignment
- User-buffered I/O
- Buffering done in user space, either manually by the application, or transparently in a library
- stdio
- Provides a platform-independent, user-buffering solution
File Pointer (similar with file descriptor)
- Inside the C library, the file pointer maps to a file descriptor
- File pointer is represented by a pointer to the FILE typedef, which is defined in <stdio.h>
Opening Files
- FILE *fopen(const char *path, const char *mode)
- Opens the file path according to the given mod
- mode
- r: open the file for reading
- r+: open the file for both reading and writing
- w: open the file for writing
- If the file exists, it is truncated to zero length; If the file does not exist, it is created
- w+: open the file for both reading and writing
- a: open the file for writing in append mode
- The file is created if if does not exist
- The stream is positioned at the EOF
- a+: open the file both reading and writing in append mode
- WHAT IS THE Difference between r+ and w+ in fopen()?
- Return value
- Upon success, a valid FILE pointer; in failure, NULL
더보기
https://stackoverflow.com/questions/21113919/difference-between-r-and-w-in-fopen
w+에서의 write()은 truncated이고, r+에서의 write()은 append이다
Opening Streams via File Descriptor
- FILE *fdopen(int fd, const char *mode)
- Converts an already open file decriptor (fd) to a stream
- mode
- Must be compatible with the modes originally used to open the file descriptor
- fd의 접근 mode와 fdopen에서의 mode가 반드시 같아야합니다.
- Return value
- Upon success, a valid FILE pointer; on failure, NULL
Reading from a Stream
- int fgetc(FILE *stream)
- Reads a single character from a stream
- Returns a character as an unsigned char cast to an int
- the return value must be stored in an int
- Storing it in a char is a common but dangerous mistake
- the casting is done to have a sufficient range for notification of EOF or error
- int로 return을 받는 이유는 EOF나 error에 대한 처리를 위해서입니다. 진짜 입력을 받을때는 unsigned char타입으로 타입캐스팅을 해줘야합니다.
- the return value must be stored in an int
- char *fgets(char *str, int size, FILE *stream)
- Reads up to one less than size bytes from stream, and stores the results in str
- size byte보다 1byte적게 읽어들입니다. 그 1byte는 \0을 위한 자리입니다
- A null character (\0) is stored in the buffer after the bytes read in
- string을 buffer로부터 읽어들인 후에는 \0을 뒤에 붙여줘야합니다
- Reading stops after an EOF of a newline character is reached
- If a newline is read, the \n is stored in str
- \n을 읽으면 읽어들이는 문자열에는 \n까지 들어가고 끝나기 때문에 또 마지막엔 \0을 붙여줘야합니다.
- Return value
- On success, str; on failure, NULL
- size_t fread(void *buf, size_t size, size_t nr, FILE *stream)
- Reads up to nr elements of data, each of size bytes, from stream into buffer pointed ay by buf
- size크기의 data를 nr개 읽겠다는 의미로, 총 읽어들이는 길이는 size * nr입니다
- Return value
- The number of elements read (not the number of bytes read!) is returned
- 읽어들인 byte수가 아닌 읽어들인 element의 수가 return됩니다.
Writing to a Stream
- int fputc(int c, FILE *stream)
- Writes the byte specified by c (cast to an unsigned char) to the stream pointed at by stream
- fgetc와 마찬가지로 쓰려는 값은 integer type이어야합니다.
- Return value
- Upon successful, c; otherwise EOF
- int fputs(const char *str, FILE *stream)
- Writes a null-delimited string to a given stream
- \0이 나올때까지 write하기 때문에 str에는 반드시 \0이 존재해야합니다.
- Return value
- On success, a nonnegative number; on failure, EOF
- size_t fwrite(void *buf, size_t size, size_t nr, FILE *stream)
- Writes to stream up to nr elements, each size bytes in length, from the data pointed at by buf
- fread()와 마찬가지로 데이터의 크기가 size인 element를 nr개 작성하는 함수입니다.
- Return value
- On success, the number of elements (not the number of bytes!) successfully written will be returned
- Return value less than nr denotes error
- fread()같은 경우는 중간에 EOF같은 것을 만나면 중간에 read가 끊기니까 return value가 nr보다 작아도 정상적으로 수행이 된 것이지만, fwrite는 nr보다 작은 값이 return되었다면 error가 발생한 것으로 해석할 수 있습니다.
Flushing a Stream
- int fflush(FILE *stream)
- Writes the user buffer to the kernel, ensuring that all data written to a stream is flushed via write()
- 사용자 수준의 buffer를 I/O에 write, read하라고 ensure하는 것입니다. 따라서 write의 경우는 OS에 write()을 호출하는 것이라서 OS 수준에서의 buffer에는 남아있을 수 있습니다. 즉 fsync()와 같은 함수까지 호출해야 OS 수준의 buffer에서도 flush가 됨을 보장합니다.
- Return value
- On success, 0; on failure, EOF
Seeking a Stream
- int fseek(FILE *stream, long offset, int whence)
- Manipulates the file position of stream in accordance with offset and whence
- whence
- SEEK_SET: the file position is set to offset
- SEEK_CUR: the file position is set to the current position plus offset
- SEEK_END: the file position is set to the end of the file plus offset
- Return value
- On success 0; on error -1
- lseek과 달리 offset을 return하지 않습니다.
- long ftell(FILE *stream)
- Returns the current stream position of stream
- On error, it return -1
Closing Streams
- int fclose(FILE *stream)
- On success, 0; on failure, EOF
- int fcloseall(void)
- Closes all streams associated with the current process, including stdin, stdout, and stderr
- std fd를 포함하는 해당 프로세스가 사용하고 있는 모든 file들을 close합니다.
Example
int main()
{
FILE *in, *out;
struct univ {
char name[100];
unsigned int year;
} u, my_univ = {"konkuk Univ.", 1931);
out = fopen("data", "w");
if(!out){
perror("fopen");
return 1;
}
if(!fwrite(&my_univ, sizeof(struct univ), 1, out)){
perror("fwrite");
return 1;
}
if(fclose(out)){
perror("fclose");
return 1;
}
in = fopen("data", "r");
if(!in){
perror("fopen");
return 1;
}
if(!fread(&u, sizeof(struct univ), 1, in)){
perror("fread");
return 1;
}
if(fclose(out)){
perror("fclose");
return 1;
}
printf("name=\"%s\" year=%u\n", u.name, u.year);
return 0;
}
'[학교 수업] > [학교 수업] 시스템 프로그래밍' 카테고리의 다른 글
[시스템 프로그래밍] Sleeping (1) | 2024.12.11 |
---|---|
[시스템 프로그래밍] Time (1) | 2024.12.03 |
[시스템 프로그래밍] I/O Redirection (1) | 2024.11.28 |
[시스템 프로그래밍] Memory Mapped I/O (1) | 2024.11.24 |
[시스템 프로그래밍] Multiplexed I/O (0) | 2024.11.24 |