系统编程-文件系统IO
注意这是我的《Linux-Unix系统编程手册》这个本书的第四章和第五章的笔记
通过的文件IO接口
在Linux中的文件结构都是通用的,这意味这使用几个函数就可以控制系统中的所有文件类型,包括终端。
这些通用接口主要是:
1 |
|
还包括一个通用接口以外的函数:ioctl()
,ioctl()系统调用又为执行文件和设备操作提供了一种多用途机制。
open()函数
这个函数就是打开一个文件,返回所打开文件的文件描述符。可以使用各种标志位来打开文件。
1 |
|
read()函数
从指定的文件中读取数据到buffer
中,返回所读取的字符个数。
如果 read()
调用成功,将返回实际读取的字节数,如果遇到文件结束(EOF)则返回 0
,
如果出现错误则返回-1
。ssize_t
数据类型属于有符号的整数类型,用来存放(读取的)字节数或-1
(表示错误)。
1 |
|
一次 read()调用所读取的字节数可以小于请求的字节数。对于普通文件而言,这有可能是因为当前读取位置靠近文件尾部。当 read()应用于其他文件类型时,比如管道、FIFO、socket 或者终端,在不同环境下也会出现 read()调用读取的字节数小于请求字节数的情况。例如,默认情况下从终端读取字符,一遇到换行符(\n),read()调用就会结束。
write()函数
这个函数参数含义和read()
函数意义一致。返回的是读取到的字符个数,注意如果 write()调用成功,将返回实际写入文件的字节数,该返回值可能小于 count 参数值。这被称为“部分写”。对磁盘文件来说,造成“部分写”的原因可能是由于磁盘已满,或是因为进程资源对文件大小的限制。
1 |
|
close()函数
关闭文件,成功返回0
,反之-1
。
lseek()函数
改变、获取文件的偏移量。返回现在文件偏移量位置。
1 |
|
lseek()并不适用于所有类型的文件。不允许将 lseek()应用于管道、FIFO、socket 或者终端。一旦如此,调用将会失败,并将 errno 置为 ESPIPE。另一方面,只要合情合理,也可以将 lseek()应用于设备。例如,在磁盘或者磁带上查找一处具体位置
文件空洞
如果程序的文件偏移量已然跨越了文件结尾,然后再执行 I/O 操作,将会发生什么情况?read()调用将返回 0,表示文件结尾。有点令人惊讶的是,write()函数可以在文件结尾后的任意位置写入数据。
在没有向其中写入数据的时候,文件空洞是不占内存的。但是一旦向其中写入一些数据,则操作系统会为这些数据分配存储空间。但是文件的大小并不会变。
所谓的文件空洞就是会占用名义存储空间,但是不会占用实际存储空间。但是对于不支持的文件空洞的文件系统来说,就会直接将数据直接存储到存储空间里。
参考资料
- 《Linux-Unix系统编程手册》