Skip to the content.

文件IO,fileIO 也可以说是系统调用IO,以文件描述符(file descriptor)为核心。

1. 文件描述符(fd)

一个进程同时打开2个文件的情况,如下图:

有几个问题:

  1. 这个文件描述符的数组的大小是多少呢?进程最大打开文件的大小;命令ulimit -n
  2. 这个数组存放在哪里?每个进程空间都会有这么个进程
  3. 一个进程可以同时打开一个文件两次吗?

  4. 可以。如下图fd4和fd5都打开了同一个文件,所以这个file的结构体中可能存在一个count的计数器,只有当没有fd正在使用该文件的时候,这个file结构体空间才会被free。

    image-20210315115820997

  5. 两个进程可以同时打开一个文件吗?

    可以。可能是这样的,不确定

    image-20210315120327640

另外,关于文件描述符的几个注意点:

2. 文件IO操作:

read write open close lseek 等,标准IO函数都是基于这5个函数实现的。

3. fileIO和stdIO的区别

4. IO的效率问题

效率问题最重要的是bufsize的选择。写一个例子mycp.c

  # BUFSIZE  循环次数    real   user  sys
				 1  373293056 662.84 31.40 628.40 
         2  186646528 301.75 13.89 287.24 
         4   93323264 148.39 6.61 141.39 
         8   46661632 87.81 3.61 83.72 
        16   23330816 51.50 2.08 48.71 
        32   11665408 26.29 1.02 24.66 
        64    5832704 13.28 0.53 12.20 
       128    2916352 6.38 0.25 5.77 
       256    1458176 9.05 0.11 2.73 
       512     729088 2.10 0.06 1.65 
      1024     364544 1.37 0.02 1.01 
      2048     182272 1.18 0.01 0.84 
      4096      91136 0.92 0.00 0.52 
      8192      45568 0.96 0.00 0.60 
     16384      22784 1.21 0.00 0.56 
     32768      11392 1.18 0.00 0.73 
     65536       5696 0.92 0.00 0.52 
    131072       2848 1.03 0.00 0.56 
    262144       1424 1.27 0.00 0.72 
    524288        712 1.29 0.00 0.78 
   1048576        356 2.65 0.00 1.07 
   2097152        178 3.37 0.00 1.22 
   4194304         89 4.72 0.00 0.92 
   8388608         45 18.91 0.00 0.65 

发现后面越来越快,是有问题的,因为都保存在文件系统缓存里了。

看APUE书中介绍有几个点:

=注意点:
使用time命令后得到的是三个时间:
real	0m0.000s   = user+sys+一点点
user	0m0.000s
sys	0m0.000s

sys:在内核或者系统调用上消耗的时间
user:用户进程中消耗的时间
real:为啥多一点点?有调度等待的时间,中断等等
用户真正在意的是real时间,而程序员在意的是user+sys时间,调度的时间程序员也无法左右。

常规用的time嵌在bash内,可以单独安装GNU的time包。time -f "%e %U %S"

5. 文件共享

题目:删除一个文件的第十行。

​ 使用getline获取一行:deleteline10-getline.c