1、Standard I/O是指ISO C的standard I/O library中的函数。
它是以stream为中心的,当我们使用standard I/O打开或者新创建一个文件的时候,我们就说为这个文件关联了一个stream(或者更近一步,就认为这个文件已经变成了一个stream).
2、UNIX中把所有的东西都看做文件,键盘也是一个文件。打开这个文件,就会返回这个文件的file descriptor。UNIX中定义这个文件为standard input file,其descriptor为STDIN_FILENO。
在ISO C Standard I/O中,所有的文件都被看做stream,键盘也会被看做stream(可能是因为定义了与之相关的buffer的缘故,用FILE指向一个stream),那么它就是一个standard input stream。这个standard input stream在ISO C Standard I/O中使用一个指针"stdin” 来表示,这个指针定义在<stdio.h>中。
(我自己理解的,可能不太准确)
3、Standard I/O Library会使用buffer进行I/O操作,目的就是尽量减少使用read() 和 write()的次数。
buffer 的种类:
· Fully buffered:当这个buffer被装满的时候,standard I/O Library会自动执行I/O操作。它一般是使用malloc函数动态指定的,一般是某个standard I/O library函数第一次对某个stream进行I/O操作的时候分配的。
· Line buffered:大小固定。当遇到newline符号时,执行I/O操作(read() or write())。
· Unbuffered:standard I/O library不提供buffer。一般standard error stream就没有buffer,及时显示。
4、据我估计
output:使用write()函数的都是output。output data, output stream …
input:使用read()函数的都是input。input data, input stream …
5、getc()和fgetc()的区别在于:前一个函数可以用macro来实现(应该根据不同的操作系统有所不同),后一个必须用函数来实现。所以,前一个使用的时候参数不能带有副作用。而后一个函数可以作为地址传给函数指针。
putc()和fputc()也是这样的区别。
6、第三章讲的read(), write(), lseek()这些函数都把file descripter这个参数放在最前面。
而第五章讲的fputs(), fgets()等函数都把FILE*这个参数放在最后面。
7、fgets()和fputs()都要求我们自己对最后的newline进行处理(这两个函数是Line-at-a-Time I/O)。fgets()会读入一个含有newline的字符串;fputs()则不会自动添加newline。这两个函数都只是对NULL进行处理,其他的都要我们自己处理。
8、Character-at-a-time I/O functions such as fgetc() and fputc()不用自己指定buffer,它们是ISO C standard I/O,由这些函数自己制定buffer,然后再调用read()或者write()函数。
Line-at-a-Time I/O functions such as fgets() and fputs(),自己指定buffer以及大小,然后这两个函数会自己调用read()或者write()函数。
(?)
9、使用standard I/O library总共会用到两个buffer、两次copy:
· 两个buffer是:standard I/O buffer--这个buffer是在kernel中的,由standard I/O library自己管理,负责直接和disk上的文件进行交互。
memory buffer--这个buffer是用户自己定义的,有可能有也可能没有。比如使用fgets()函数时就需要自己定义一个memory buffer,而使用getchar()函数的时候就不需要自己定义一个memory buffer(虽然我们没有自己定义的memory buffer,但是standard I/O buffer依旧在kernel中存在,依旧进行着buffered I/O)。
· 两次copy是:一次是从disk file到kernel中的standard I/O buffer。这是通过使用read() write()函数通过进行系统调用实现的。
一次是从standard I/O buffer到我们自己定义的memory buffer(如果我们自己定义了这个buffer的话)。这个过程可能是通过调用一些memory copy函数实现的。