@SiberiaBear
2015-10-19T09:23:48.000000Z
字数 1961
阅读 2015
Linux
固定地址:https://www.zybuluo.com/SiberiaBear/note/197039
在UNIX中,可以通过读写文件这一个单一接口来处理任何外围设备与程序之间的通信。
每当运行一个程序在shell中时,它都将打开3个文件,对应于文件描述符中为0,1,2,依次表示标准输入、标准输出、标准错误,从0中读取,并写入到1和2中,这样就不必操心打开文件的问题。另外,程序使用者可通过如下命令重定向程序的I/O:
prog <输入文件名> 输出文件名
程序并不会知道0,1,2的改变是怎么实现的,都是由操作系统完成。
输入输出是由read和write函数实现的。这两个函数,第一个参数是文件描述符,第二个是程序中存放读或写的数据的字符数组,第三个参数是要传输的字节数。
int n_read = read(int fd, char *buf, int n);
int n_written = write(int fd, char *buf, int n);
每个函数调用都会返回实际传输的字节数。在读文件时,返回值可能会小于请求的字节数,是因为读到文件即将到末尾而不满足一次读出n个长度的字节,也可能返回0,表示已经读到了文件的末尾,可能返回-1,表示发生了某种错误;在写文件时,返回值是实际写入的字节数,如果返回值与请求写入的字节数不相等,则表示发生了某种错误。
除了默认的stdin、stdout、stderr之外,其他文件必须在读写之前显式的打开,使用open和creat实现。
注意:open
函数与fopen
不同,open函数返回的是一个文件描述符,是一个比较小的int型数值,返回-1代表发生错误,而fopen返回的是文件指针。
int open(char *name, int flags, int perms);
其中name是一个包含文件名的字符串,flags是一个int类型的值,表示以何种方式打开文件,主要有:
O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR 以读写方式打开文件
perms的值可以始终为0,perms代表权限值。
open函数打开一个不存在的文件会错误。creat可以创建文件或覆盖已有旧文件。
int creat(char *name, int perms)
如果创建成功将返回文件描述符,否则返回-1。如果创建的文件已经存在,则会直接覆盖原文件,原文件数据将丢失,并不会导致错误。
可以用perms指定创建文件的权限,用4位的八进制数表示权限值(特殊权限、文件所有者权限、文件所有者组权限和其他成员权限)。
函数
close(int fd)
用于断开文件描述符和已打开文件之间的连接,并释放文件描述符,供其他文件使用。close
与fclose
类似,但它不需要刷新(flush)缓冲区。如果程序通过exit
函数退出或返回到主函数,所有打开的文件将会被关闭。
函数
unlink(char *name)
用于将文件name从文件系统中删除。
系统调用lseek可以在文件中任意移动位置而不实际读写任何数据:
long lseek(int fd, long offset, int origin);
将文件描述符为fd的文件的当前位置设置为offset,其中,offset是相对于orgin指定的位置而言的,随后的读写操作将从此位置开始。origin的值为0,1,2,分别用于指定偏移offset从文件的开始、当前位置或从文件的结尾处算起,发生错误返回-1。lseek
和fseek
类似,但fseek
的第一个参数是文件指针,且发生错误返回非零值。
标准库中的文件不是由文件描述符描述的,而是使用文件指针描述的。文件指针是一个指向包含文件各种信息的结构的指针,该结构包含下列内容:一个指向缓冲区的指针,通过它可以一次读入文件的一大块内容;一个记录缓冲区中剩余的字符数的计数器;一个指向缓冲区中下一个字符的指针;文件描述符;描述读/写模式的标志;描述错误状态的标志等。
FILE *fopen(char *name, char *mode);
其中mode可以为r
w
a
,r为只读,w为创建文件,a为在文件末尾补充。
int _fillbuf(FILE *fp)
如果_fillbuf函数发现所打开的文件不是以只读方式打开,则返回EOF,否则将试图分配一个缓冲区,建立缓冲区后,_fillbuf调用read填充缓冲区,设置计数值和指针,并返回缓冲区的第一个字符。