

Buffered I/O#
Standard Library of C#
- Call
fopen()會得到一個 file object pointer 會放在 Virtual Memory
FILE *fopen(const char *pathname, const char *type);
- 可以 support atomic operation

FILE *freopen(const char *pathname, const char *type, FILE *fp);
- 可以指定某個 fp (通常是常見 e.g.
STDOUT) 來放這個 file -
cFILE *fp; fp = freopen ("/tmp/logfile", "a+", stdout); printf(“Sent to stdout and redirected to /tmp/logfile”); fclose(stdout);
FILE *fdopen(int fildes, const char *type);
- 做 unbuffer I/O 後想重新指定型別,所以可以把開好的 fd 來指定型別
- 一定要是前一個 open 的 subset
- 如果此時開成
w會沒有 truncate
int fileno(FILE *fp);
- 得到
fd
int fclose(FILE *fp);
- fstream 裡面的 buffer 必須有效
- 可以把裡面的東西
- Discard Input
- Flush Output
-
cFILE *open_data(void) { FILE *fp; char databuf[BUFSIZ]; /* setvbuf makes this the stdio buffer */ if ((fp = fopen(DATAFILE, "r")) == NULL) return (NULL); if (setvbuf(fp, databuf, _IOLBF, BUFSIZ) != 0) return (NULL); return (fp); } - 這裡的
databuf是 local 的出去之後fclose會失效
Buffering#
- 最主要目的是要減少 system call 的次數
- Call standard I/O 會自動 allocate 但是也可以自行
setbuf(),setvbuf() - 最終會往 Unbuffer I/O 送
Fully Buffered#
- Default 通常是這個 e.g. Disk, Pipe, Socket
- 滿了才會送出去,才 trigger Unbuffer I/O
Line Buffered#
- New line 就會送一次 e.g. terminal
- 兩種情況要特殊處理
- Full: 滿了就一定得送出去
- Flush: 系統要求一定要馬上 flush
- 下面這個 code,新一行雖然沒看到
\n但 terminal 必須先輸出$ -
cchar buf[100]; printf(“$ “); scanf(“%s”, buf);
- 下面這個 code,新一行雖然沒看到
Unbuffered#
- 需要有錯誤就馬上輸出
stderr
int fflush(FILE *fp);
- 把
fp裡面的 buffer 內容透過 Unbuffer I/O 送出去 - 如果設定
fp == NULL就會把所有 output buffer 送出去 - 送是送到 buffer cache 而不是直接進去 DISK 還要呼叫
sysc(),fsysc(),fdatasysc()
void setbuf(FILE *fp, char *buf);
- 沒指定 size 會是 system 指定 type
int setvbuf(FILE *fp, char *buf, int mode, size_t size);
- 可以指定 size,也就是 type 可以指定
- 透過
stat去得到 file metadata_IOFBF,_IOLBF,_IONBF
long ftell(FILE *fp);
- 找尋目前
offset
int fseek(FILE *fp, long offset, int whence);
- Binary file
SEEK_END無用因為 buffer 性質會 append 一堆奇怪東西 - Text file
SEEK_SET就是 0 或著ftell()的 return value
Unformatted I/O#
- Character-at-a-time I/O, e.g.,
getc()- Buffering handled by standard I/O lib
- Line-at-a-time I/O, e.g.,
fgets()- Buffer limit might need to be specified.
- Direct I/O, e.g.,
fread()- Read/write a number of objects of a specified size
Character-at-a-time I/O#
int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);
getc()有可能是 macro,getchar()必定是 function-1會是 EOF 或 Error
int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);
putc()有可能是 macro,putchar()必定是 function
char *fgets(char *buf, int n, FILE *fp);
\0才會停下,\n會被讀入
char *gets(char *buf);
- 沒有指定 buffer size,會 overflow.
char *fputs(const char *str, FILE *fp);
char *puts(const char *str);
- 一個一個 string 寫入 terminal,沒有 overflow 的問題
size_t fread(void *ptr, size_t size, size_t nobj, FILE *fp);
size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE *fp);
- Binary I/O
- 可以一個一個 Object 寫入
-
cstruct { short count; long total; char name[NAME_SIZE]; } item; if (fwrite(&item, sizeof(item), fp) != 1) err_sys("fwrite error");
Input Functions:
int scanf(const char *format, …);int fscanf(FILE *fp, const char *format, …);int sscanf(char *buf, const char *format, …);
Output Functions:
int printf(const char *format, …);int fprintf(FILE *fp, const char *format, …);int sprintf(char *buf, const char *format, …);Overflow is possible for sprintf() –- ‘\0’ appended at the end of the string. A better substitute:
snprintf() int vprintf(const char *format, va_list arg);int vfprintf(FILE *fp, const char *format, va_list arg);int vsprintf(char *buf, const char *format, va_list arg);
Standard I/O Performance#
| Function | User CPU (s) | System CPU (s) | Clock Time (s) | Bytes of Program Text |
|---|---|---|---|---|
Best time using read/write | 0.01 | 0.18 | 6.67 | – |
fgets, fputs | 2.59 | 0.19 | 7.15 | 139 |
getc, putc | 10.84 | 0.27 | 12.07 | 120 |
fgetc, fputc | 10.44 | 0.27 | 11.42 | 120 |
Single byte using read/write | 124.89 | 161.65 | 288.64 | – |
- 真正用 System CPU 的時間,Best use 跟其他 Standard Library 的其實一樣
- Standard library 是在節省 System CPU time
int fwide(FILE *fp, int mode)
- Standard I/O in C lib 會有 orientation
- single byte character
- multiple byte character
- 一但被 set 就不能 reset
Back to the content
NTU PJ System Programming
2025 Fall
← Back to the content