unix----文件I/O

1. open函数

    #include <fcntl.h>

    int open(const char *pathname, int oflag, .../* mode_t mode*/);

    返回值:成功返回文件描述符,出错返回-1

    oflag参数:

    O_RDONLY 只读打开

    O_WRONLY 只写打开

    O_RDWR 读写打开

    (这三个常量有且只能指定一个,以下常量可选)

    O_APPEND 追加写

    O_CREAT 若文件不存在就创建,需要第三个参数mode,这个的具体设置以后再看。。

    O_EXCL 如果同时指定了O_CREAT,并且文件存在就会出错。用这个常量可以测试一个文件是否存在,如果不存在,则创建这个文件,这是一个原子操作。//这个需要测试下。。。

    O_TRUNC 如果此文件存在,且为只写或者读写打开,文件长度置为0

    O_NOCTTY 如果pathname指的是终端设备,则不将该设备分配作为此进程的控制终端。//这个不太懂。。

    O_NONBLOCK 如果pathname指的是一个FIFO,一个块特殊文件或者一个字符特殊文件,则此选项为文件的本次打开操作和后续的I/O操作设置非阻塞模式。//这个不懂。。。

    (Single UNIX Specification)

    O_DSYNC,O_RSYNC,O_SYNC.//不懂。。。。

    注:open返回的文件描述符一定是最小的未用描述符数值。。

2. creat函数

    #include<fcntl.h>

    int creat(const char *pathname, mode_t mode);

    返回值:成功返回只写打开的文件描述符,若出错则返回-1;

 

    此函数等效于: open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);

3. close函数

    #include<unistd.h>

    int close(int filedes);

    返回值:成功返回0,若出错返回-1。

4. lseek函数

    #include<unistd.h>

    off_t lseek(int fileds, off_t offset, int whence);

    返回值:成功返回新的文件偏移量,若出错则返回-1。

    whence: SEEK_SET, SEEK_CUR, SEEK_END。

    注:空洞文件,文件偏移量可以大于文件的当前长度,在这种情况下对该文件的下一次写操作将加长文件,并在文件中构成一个空洞,这一点是允许的,位于文件中单没有写过的字节都被读为0。文件中的空洞并不要求在磁盘上占用存储区。当定位到超出文件尾端之后写时,对于新写的数据需要分配磁盘块,但是对于原文件尾端和新开始写位置之间的部分则不需要分配磁盘块。

5. read函数

    #include<unistd.h>

    ssize_t read(int filedes, void *buf, size_t nbytes);

    返回值:成功返回读到的字节数,若已到文件结尾返回0,若出错则返回-1。

    注:size_t 是为了方便系统之间的移植而定义的

          在32位系统上 定义为 unsigned int
          在64位系统上 定义为 unsigned long

          更准确地说法是 在 32位系统上是32位无符号整形
          在 64位系统上是64位无符号整形

          size_t一般用来表示一种计数,比如有多少东西被拷贝等

    另:以下情况可以使实际读到的字节数少于要求读的字节数:

          1)读普通文件时,在读到要求字节数之前已到达了文件尾端。

          2)当从终端设备读时,通常一次最多读一行。

          3)当从网络读时,网络中的缓冲机制可能造成返回值小于所要求读的字节数。

          4)当从管道或FIFO读时,如管道包含的字节少于所需的数量,那么read将只返回实际可用的字节数。

          5)当从某些面向记录的设备(如磁带)读时,一次最多返回一个记录。

          6)当某一信号造成中断,而已经读了部分数据量时。

6. write函数

    #include<unistd.h>

    ssize write(int filedes, const void *buf, size_t nbytes);

    返回值:成功返回已写的字节数,出错返回-1。

    注:其返回值通常与参数nbytes的值相同,否则表示出错。出错的常见原因是:磁盘已写满,或者超过了一个给定进程的文件长度限制。

7. 文件共享。UNIX内核使用三种数据结构表示打开的文件,如下图:

8. 原子操作

    #include<unistd.h>

    ssize_t pread(int filedes, void *buf, size_t nbytes, off_t offset);

    返回值:读到的字节数,若已到文件结尾则返回0,若出错则返回-1。

    ssize_t pwrite(int filedes, const void *buf, size_t nbytes, off_t offset);

    返回值:若成功返回已写的字节数,若出错则返回-1。

    注:pread相当于顺序调用lseek和read,区别如下:

          *调用pread时,无法中断其定位和读操作。

          *不更新文件指针。

9. dup和dup2

    #include<unistd.h>

    int dup(int filedes);

    int dup2(int filedes, int filedes2);

    返回值:若成功则返回新的文件描述符,若出错则返回-1。

    注:1. 由dup返回的新文件描述符一定是当前可用文件描述符中的最小值。用dup2则可以用filedes2参数指定新描述符的数值。如果filedes2已经打开,则先将其关闭。如若filedes等于filedes2,则dup2返回filedes2,而不关闭它。这些函数返回的新描述符与参数filedes共享同一个文件表项。

          2. 复制一个描述符的另一种方法是使用fcntl函数。

              dup(filedes);等效于fcntl(filedes, F_DUPFD, 0);

              dup2(filedes, filedes2);相当于 close(filedes2); fcntl(filedes, F_DUPFD, filedes2);

              后面的区别是:dup2是一个原子操作,而且同fcntl也有些不同的errno。

10. sync、fsync和fdatasync函数

      前导:延迟写减少了磁盘读写次数,但是却降低了文件内容的更新速度,使得欲写到文件中的内容在一段时间内并没有写到磁盘上。当系统发生故障时,这种延迟写可能造成文件更新内容的丢失。为了保证磁盘上实际文件系统与缓冲区高速缓存中内容的一致性,UNIX系统提供了sync、fsync和fdatasync三个函数。

      #include<unistd.h>

      int fsync(int filedes);

      int fdatasync(int filedes);

      返回值:成功返回0,若出错返回-1。

      void sync(void);

      注:sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,并不等待实际写盘操作结束。

            fsync函数只对由文件描述符filedes指定的单一文件起作用,并且等待写磁盘操作结束,然后返回。可用于数据库这样的应用程序,这种应用程序确保将修改过的块立即写到磁盘上。

            fdatasync函数类似于fsync,但它只影响文件的数据部分,而fsync还会同步更新文件的属性。

11. fcntl函数

      #include<fcntl.h>

      int fcntl(int filedes, int cmd, .../*int arg*/);

      返回值:若成功,则依赖于cmd,出错则返回-1。

      说明:fcntl允许仅知道打开文件描述符时可以修改其性质。

      五种功能:

      1)复制一个现有的描述符(cmd=F_DUPFD);

           功能同dup2,但是新描述符有它自己的一套文件描述符标志,其FD_CLOEXEC文件描述符标志被清除。

      2)获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD);

           当前只定义了一个文件描述符标志FD_CLOEXEC。

      3)获得/设置文件状态标记(cmd=F_GETFL或F_SETFL);

                   

文件状态标志

说明

O_RDONLY

只读打开

O_WRONLY

只写打开

O_RDWR

读写打开

O_APPEND

每次写时追加

O_NONBLOCK

非阻塞模式

O_SYNC

等待写完成(数据和属性)

O_DSYNC

等待写完成(仅数据)

O_RSYNC

同步读、写

O_FSYNC

等待写完成(仅FreeBSDMac OS X

O_ASYNC

异步I/O(仅FreeBSDMac OS X

           若想取得三个访问方式标志首先必须用屏蔽字O_ACCMODE取得访问模式位,然后将结果与这三种值中的任一种作比较。

           可以更改的标志是除访问方式标志以外的7个标志。

           这里设置O_SYNC标志与fsync和fdatasync函数相比较,fsync和fdatasync在我们需要时更新文件内容,O_SYNC标志则在我们每次写至文件时更新文件内容。

      4)获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN);

           取得或者设置接收SIGIO和SIGURG信号的进程ID或进程组ID。正的ID表示进程,负的ID表示进程组。

      5)获得/设置记录锁(cmd=F_GETLK、F_SETLK或F_SETLKW)。

12. ioctl函数(不能用一般函数表示的I/O操作)

      #include<unistd.h> /* System V*/

      #include<sys/ioctl.h> /*BSD and Linux*/

      #include<stropts.h> /* XSI STREAMS*/

      int ioctl(int filedes, int request, ...);

      返回值:若出错返回-1,成功返回其他值。

      ...处通常是指向一个变量或结构的指针。

13. /dev/fd

      目录项:名为0、1,、2等的文件,打开文件/dev/fd/n等效于复制描述符n(假定描述符n是打开的)

14.结束语:

     1)不调用fcntl实现dup2。循环使用dup生成新的描述符,然后找到新描述符后挨个关掉。需要注意的是两个描述符相同的情况。

     2)dup2(fd,0);dup2(fd,1);dup2(fd,2);if(fd>2) close(fd);??

     3)./a.out > outfile 2 > &1表示1,2同时定向到outfile

          ./a.out  2>&1 > outfile 表示2定向到标准输出,1定向到outfile。

     4)以添加方式打开文件,如果是读,可以使用lseek,而write不行。

 

 

这一章就此结束。。。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值