apue第三章(2)

    技术2022-05-20  32

     

     我的理想是:“让我的家人生活得更好”

    6、几个io系统调用

    都在 fcntl.h

    fcntl.h  sys/types.h                             

    open(char * path, oflag, …/*mode_t mode*/)

    第一个参数是文件的名字 最长不要超过MAX_NAME

    第二个参数是打开文件参数

    第三个是创建文件时候提供的umask

    第二个参数一般使用:

    O_RDONLY 只读的方式打开

    O_WRONLY 只写的方式打开

    O_RDWR   读写方式打开

    O_CREAT 如果文件不存在则创建一个文件,如果文件存在,返回-1

     

     O_EXCL  如果设置了参数O_CREAT ,如果文件不存在,则创建文件的操作为原子操作

    O_TRUNC 如果文件存在则把文件长度设置为0

    O_SYN    当进行写操作时候,需要完成物理写操作后,再返回

    O_NOBLOCK 如果是打开一个fifo文件,一个块特殊文件,一个字符文件,此次操作和后续的io为非阻塞方式。

     

    Open的每次打开一个文件返回的都是当前最小的可用的文件描述符

     

    fcntl.h  sys/types.h                             

    int lseek(int fid, off_t  offset, int where)

    返回新的文件位移 出错返回-1

    第一个参数是问价描述符

    第二个参数是一个 偏移量,第三个参数是参考点

    对于第三个参数

    SEEK_SET 把偏移到距离文件开头offset

    SEEK_CUR 把距离当前的偏移量offset

    SEEK_END 偏移量为文件长度+ offset

     

    如果文件偏移量大于文件长度,中间会形成一个空洞,空洞会被设置为/0

     

    可以使用 pos = lessk(fid, 0 ,SEEK_CUR);来判断一个文件是否支持偏移量

    #include<fcntl.h>

    #include<stdio.h>

    #include<unistd.h>

     

    int main()

    {

       int pos = -1;

       if((pos = lseek(STDIN_FILENO,0,SEEK_CUR)) == -1)

         printf("can't seek/n");

       else printf("can seek/n");

    }

    root@white-desktop:/home/junjun/apue/chapter3# ./lseekTest.out  < lseekTest.c

    can seek

     

    unistd.h:

    ssize_t read(int fd, void * buf, size_t nbytes)

    read成功 返回读到的字节数,如果达到文件结尾则会返回0 错误返回-1

    每读一侧 文件偏移量会想后移动读到的字节数。

     

    Unistd.h

    ssize_t write(int fd, void * buf, size_t nbytes)

    向文件描述符为fd的文件写入nbytes个字节,返回写入的字节数。如果

    返回的字节数小于nbytes则出错。在每一次成功写入后,文件偏移量向前移动实际写入的字节数。如果设置了O_APPEND,每次操作之前将文件的偏移量设置为结尾。

     

    7、文件的共享,不同程序之间打开同一个文件。

    三层结构:

    文件描述符表  -- > 文件表项 -- > v节点

    1、每一个进程都有一个文件描述符表,每一个表项有对应的文件描述符,和指向文件表的指针。

    2、文件表包含了当前的文件偏移,文件状态标志(读写,同步,阻塞等)

    和指向v节点的指针。

    3V节点(Vvirtual file system 的头个字母),虚拟文件系统是为了一个系统有多个文件系统的情况下使用,v节点中包含了指向i节点的指针,文件的拥有者,文件大小,已经在磁盘的位置信息等都放在v节点中。

     

    8 dup

    复制文件描述符

    int dupint fd

    复制文件描述符,返回能够使用的最小的文件描述符。否则返回-1.

    例如:

    fd1 = dup(fd2);

     fd1fd2指向同一个文件表,也就是有相同的文件状态标示。相同的文件偏移量。fork后父子进程都有相同的文件描述符表,都指向相同的文件表。

     Int dup2(int fd1, int fd2);

    返回新的文件描述符,fd2指向fd1指向的文件描述符。如果fd2已经打开则关闭fd2.

     

     9,fcntl

    int fcntl(int filde, int cmd, ……);

    改变打开文件的性质。

    用得比较多的是:取得和修改文件描述符标志:F_SETFD, F_GETFD

     例如

    #include<fcntl.h>

    #include<unistd.h>

    #include<sys/types.h>

    #include<stdio.h>

    #include<stdlib.h>

    int main(int argc , char * argv[])

    {

       int val, val1 = 0;

       int fd = open("testfcntl.txt",O_RDONLY|O_APPEND|O_SYNC);

       if((val1 = fcntl(fd,F_GETFL,0)) < 0)

       {

           perror("error");

           return -1;

       }

       printf("fd = %d /n",fd);

       val = val1 & O_ACCMODE;

       if(val == O_RDONLY) printf("rdonly ");

       else if(val == O_WRONLY) printf("wronly " );

       else if(val == O_RDWR) printf("rdwr ");

       else  printf("unknow mode ");

       if(val1 & O_APPEND) printf(",append");

    #if defined(O_SYNC)

       if(val1 & O_SYNC) printf(",syn");

    #endif

           printf("/n");

    close(fd);

    }

     

    white@white-desktop:/home/junjun/apue/chapter3$ ./a.out

    fd = 3

    rdonly ,append,syn

               注意 O_REONLY O_REDWR O_WRONLY 是互斥的,必须与O_ACCMODE屏蔽字相与得到读写状态

     

    可以使用 fcntl(fd, F_SETFL, val),来设置文件描述符状态。

     


    最新回复(0)