文件I/O(一)

Unix系统内核来说,所有打开文件都是通过文件描述符来操作的。文件描述符是一个非负整数。打开,创建文件,系统内核就会返回一个文件描述符号。

  • 0与进程标准输入关联
  • 1与进程标准输出关联
  • 2与标准错误关联

1.1、函数 lseek

检测标准输入是否可以被设置偏移量

1
2
3
4
5
6
7
8
9
10
11
#include "apue.h"

int main(int argc, char const *argv[])
{
if(lseek(STDIN_FILENO,0,SEEK_CUR) == -1){
printf("connot seek\n");
}else{
printf("seek OK \n");
}
return 0;
}
  • SEEK_CUR : 相对于当前位置的偏移量
  • SEEK_END :相对文件末尾偏移量
  • SEEK_SET : 相对文件开头偏移量

文件偏移量如果大于当前文件长度会发生什么?

创建一个文件,写入abcdefghij,设置偏移量,写入ABCDEFGHIJ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "apue.h"
#include<fcntl.h>

char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";
int main(int argc, char const *argv[])
{
int fd;
if ((fd = creat("file.hole",FILE_MODE))<0) {
printf("buf1 write error");
}

if ((write(fd,buf1,10)) != 10){
printf("write errpr");
}
if ((lseek(fd,1024,SEEK_SET)) == -1){
printf("lessk error");
}

if ((write(fd,buf2,10)) != 10){
printf("write errpr");
}
return 0;
}
  • 支持偏移量大小设置大于文件当前大小
  • 偏移量大于文件大小,第二次写会造成文件空洞。空洞区被设置为0
  • 文件空洞不占据磁盘空间。

Tips: 使用off_t可以平台自适应大小合适的额数据类型。

1.2、函数 read

  • 读取普通文件,要求读100,但是文件长度为30,则读取成功返回30,第二次读取返回0
  • 从终端设备读,通常一次读一行
  • 当从网络读,网络中的缓冲机制可能造成返回值小于所要求读取的字节数
  • 当从管道读时,管道字节数小于要求读的字节数,则只返回有效字节数。

1.3、函数 write

  • 成功返回要求写的数量,否则失败
  • 从文件当前偏移量开始写。
  • 写成功后,偏移量增加当前写的字节数

1.4、I/O效率

大多数文件系统采用”预读“的技术,提高性能。当操作系统检测到正在进行的顺序读取时,系统就会尝试读取比应用要求更多的数据,假想很快应用就会读这些数据。

在做读取操作的时候,小缓冲区时钟时间可能和大缓冲区时钟时间相差不多。