学习Linux系统编程-Day(8)

1.read系统调用用来读取文件内容,其函数原型如下:
在这里插入图片描述
注意调用read系统调用需要添加头文件unistd.h,在read的参数中fd表示要读取的文件描述符,buffer是接收读取结果的缓冲区,count是最多能读取的字节数量。注意buffer需要用户自行申请并将缓冲区首地址传入,所以这个自行申请的缓冲区一定不要开得太小了,起码要大于count个字节。返回值是实际读取的字符数量,注意类型是ssize_t,这是一个有符号类型数,出错时返回-1。

实际上在调用read系统调用时,读取的数据字节数可能会小于count,所以count未必严格等于要读入的数据字节数,count只表示我们期望和假定要读入的数据字节数,事实上可能因为数据快读完了,根本读不满count个字节数据。

书上其实还讲到了一个例子,也就是使用read从终端读取字符串,这里书上特别强调了要显式的在读取缓冲区末尾加上’\0’来表示字符串结束,否则这里可能会因为找不到合理的串结束位置而输出错误的串。
在这里插入图片描述
测试一下这个函数,输入字符串"hello":
在这里插入图片描述
可以看到返回值为6,看来包含了换行符’\n’,但是字符串打印出来之后发现不多不少,查看每一个字符发现10后面是0,说明正好碰上了一个结束字符\0。
再测试一次,输入’meiyuan’,这一次就输出了乱码,所以还是最好在字符串缓冲区末尾加上’\0’来确保正确性。
在这里插入图片描述
2.write系统调用和read系统调用几乎是完全对称的,用于向某个文件写入数据,函数原型如下:
在这里插入图片描述
fd指向要写入的文件标识符,buffer是要写入的数据所在的缓冲区,count是期望写入的数据字节数量,返回值是是实际写入的字节数,这个字节数可能小于count,原因可能是磁盘满或文件大小达到上限。

3.close系统调用用来关闭一个文件,将被占用的文件描述符还给进程,当一个进程结束时也会自动释放所有它占用的文件描述符。因为文件描述符也是一种重要的资源,所以在一个文件操作完毕时十分有必要释放掉它的文件描述符,否则文件描述符有可能耗尽。
在这里插入图片描述

4.lseek系统调用用来显式的调整文件偏移量(默认情况下读写会隐式的改变偏移量,文件偏移量由内核来维护)。文件偏移量描述的也就是当前文件的读写指针指向的字节地址,这个函数可以用来调节读写指针的位置,函数原型如下:
在这里插入图片描述
fd指向要操作的文件的标识符;offset指偏移地址,类型是off_t类型,这是一个长整型数,lseek开头的l也来自于此,但是光有偏移地址还不够,还得指明是相对哪个基准点的偏移地址,这样才能唯一标明最终指针位置,这就是whence参数。whence参数有三个宏可以来选择,分别是SEEK_SETSEEK_CURSEEK_END,分别指当前位置尾后位置。正如编程语言里处处存在的左闭右开区间,这里的SEEK_END指向的也并不是文件最后一个字节,而是最后一个字节的下一个字节。
在这里插入图片描述
此函数的返回值是相对于文件开头的偏移量,有了这个返回值,这个函数的功能就大大扩展了,不仅可以用来调整文件指针位置,还可以用来测量文件大小等,比如lseek(fd, 0, SEEK_END)返回的值恰好也是文件中的字节数量。下面是几个例子:
在这里插入图片描述

5.跨越文件结尾之后仍可以使用read,write系统调用读取和写入数据,read系统调用会返回0表示文件结尾,而write调用还可以正常写入数据。write系统调用在写入点和之前文件结尾之间可能有一段空档(取决于write系统调用的写开始点),这其中没有写入有效的用户数据,被称为文件空洞。文件空洞在很多UNIX实现上是不额外为其分配磁盘存储空间的,因此一个文件的名义大小可能要大于它在磁盘上实际占用的字节数,这就是因为有文件空洞的存在。

6.对于通用IO模型以外的设备,可以使用ioctl系统调用来操作,这部分细节以后慢慢填上。

猜你喜欢

转载自blog.csdn.net/zzy980511/article/details/115286514