Unix环境高级编程学习笔记 第三章 文件I/O

第三章 文件I/O

  1. 引言:UNIX文件I/O只用5个函数:open、read、write、lseek、close;以上为不带缓存的I/O,指每个read和write都调用内核中的一个系统调用。不是ANSI C的组成部分,时POS1X.1和XPG3的组成部分

  2. 文件描述符:所有打开文件都由文件描述符引用,为一个非负整数。打开或创建时内核向进程返回一个文件描述符。读写时,用open或creat返回文件描述符来表示该文件,将其作为参数传给read或write。

    shell时文件描述符0与进程的标准输入结合,1与标准输出,2与标准出错输出。

  3. open函数

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    int open(const char *pathname, int oflag, .../* ,mode_t mode*/);)
    
    1. oflag参数(定义在<fcntl.h>):O_RDONLY(只读,0);O_WRONLY(只写,1);O_RDWR(读写,2) ;O_APPEND(写加到文件尾);O_CREAT(文件不存在就创建,需同时说明第三个参数mode,用于说明新文件的存取许可权位);O_EXCL(测试文件是否存在,若不存在则创建此文件成为一个原子操作);O_TRUNC(文件存在且以只读或只写打开则将其长度截短为0);0_NOCTTY(若pathname为终端设备,则不将此设备分配为此进程的控制终端);O_NONBLOCK(若pathname指的时一个FIFO、块特殊文件或字符特殊文件,则为此文件的本次打开操作和后续的I/0操作设置非阻塞方式);0_SYNC(时每次write都等到物理I/O操作完成)
    2. 文件名和路径名截短:POSIX.1中,常数_POSIX_NO_TRUNC决定是否截短过长的文件名和路径名,或者返回出错。
  4. close函数:关闭文件时也释放该进程加在该文件上的所有记录锁。进程终止时打开的文件都由内核自动关闭。

    #include <unistd.h>
    int close(int filedes);
    
  5. lseek函数:每次打开文件都有一个相关联的“当前文件位移量”,为非负整数,用以度量从文件开始处计算的字节数,通常读写都从当前文件位移量处开始,并使其增加所读写的字节数,除非指定O_APPEND,否则位移量设置为0。

    #include <sys/types.h>
    #include <unistd.h>
    
    off_t lseek(int filedes, off_t offset, int whence);//成功返回新的文件位移,出错为-1
    
    1. whence参数值:

      SEEK_SET(将文件的位移量设为距文件开始处offset个字节);SEEK_CUR(将位移量设为当前值加offset,offset可正可负);SEEK_END(将位移量设为文件长度加offset)

    2. 可使用上一个文件打开的返回值确定打开文件的当前位移量,也可确定所涉及文件是否可以设置位移量。

    3. lseek不进行I/O操作,该位移量用于下一个读写操作,文件位移量可以大于当前长度,下一次写会延长该文件并构成空调,读为\0。

  6. read函数:

    读到字符少于要求情况:

    读文件时,读到要求字节数前就已到尾端;

    从终端设备读,一次最多读一行;

    从网络读,网络中的缓冲机构可能造成返回值小于要求;

    某些面向记录的设备,如磁带,一次最多返回一个记录

#include <unistd.h>
ssize_t read(int filedes,void buff,size_t nbytes)//返回读到的字节数,到文件尾为0,出错为-1
  1. write函数

    #include <unistd.h>
    ssize_t wirte(int filedes,const void * buff,size_t nbytes);//成功返回已写字节数,出错-1
    
  2. I/O效率

    选取不同一次读写字节大小对效率有影响,在8192字节处已经最快,在增大也不会加快

  3. 文件共享:UNIX支持不同系统间共享打开文件。内核使用了三种数据结构,决定了文件共享方面进程对另一个进程的影响。

    请添加图片描述

    每个打开文件都有一个v节点结构,包含文件类型,指针等,还包含该文件的i节点(索引节点,其中含有文件所有者、长度、所在设备、指向文件在盘上使用的实际数据块的指针等)

    请添加图片描述

    进程在文件描述符上打开文件,文件描述符标志与文件状态标志不同,后者适用于文件表项的任何进程中的所有描述符

  4. 原子操作:UNIX防止多个进程同时修改文件冲突,就是使内核每次对文件进行写之前将进程的当前位移量设置到文件的尾端。

    一般而言,原子操作(atomic operation)指的是由多步组成的操作。如果该操作原子地执行,则或者执行完所有步,或者一步也不执行,不可能只执行所有步的一个子集。

  5. dup和dup2(为原子操作):用于复制一个现存的文件描述符

  6. fcntl函数:改变打开文件的性质

    #include <sys/types.h>
    #include <unistd.h>
    #include <fcntl.h>
    int fcntl(int filedes, int cmd,.../* int arg * / ) ;
    返回:若成功则依赖于c m d(见下),若出错为-1
    

    功能:复制现存的描述符;获得/设置文件描述符标记;获得/设置文件状态标志;获得/设置异步I/O有权;获得/设置记录锁

  7. ioctl:不能用本章中其他函数表示的I/O操作通常用ioctl表示。

  8. /dev/fd:为目录,目录项为名为0、1、2等的文件,打开文件/dev/fd/n等效与复制描述符n

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值