APUE学习笔记 - Chapter 3. File I/O

1.文件描述符  

     在内核中,每个打开的文件都是一个文件描述符,每个文件描述符都是一个非负整数,从0到OPEN_MAX。
     在UNIX系统中,总是将0与标准输入关联,1与标准输出关联,而2与标准错误输出关联,但是这不是所有的程序与shell都是坚持的标准,因此最好使用POSIX定义的STDIN_FILENO,STDOUT_FILENO与STDERR_FILENO来表示。
  
2.打开文件:
          int open( const char * pathname , int oflag ... ) ;
3.关闭文件:
          int close( int filedes ) ; 
          当一个进程结束的时候,所有打开的文件都会自动被内核关闭。
4.查找位置:
          每个文件打开后都会将文件偏移量设为0,除非设定了O_APPEND的模式。
          off_t lseek( int filedes , off_t offset , int whence ) ;
          通过whence可以设定offset是针对首位置,当前位置,还是末位置。
          
          经典应用:显示当前文件的长度:
                              off_t currpos ; 
                              lseek( fd , 0 , SEEK_END ) ;
                              currpos = ftell( fd ) ;
            lseek只是修改文件的偏移量,不会造成IO操作。
           将文件偏移量设置超越文件长度后再写入会造成文件的洞,所有没有写入过就进行读取的数据都会返回0。文件的洞不会造成存储的增加。
5.读取数据
            ssize_t read( int filedes , void * buf , size_t nbytes ) ; 
            
6.写入数据
            ssize_t write( int filedes , const void * buf , size_t nbytes ) ; 
7.文件结构:
     APUE学习笔记 - Chapter 3. File I/O_第1张图片
          在系统中,每个进程都维持一个文件描述符的列表,每个列表都记录着当前进程打开的文件描述符列表,每个文件都对应着一个file entry table,每个table记录着文件打开的flag,当前的文件偏移量,和指向全局的v-node节点。 v-node节点是全局性数据。在UNIX系统中,支持多个进程打开同一个文件,则每个文件指向同一个v-node结构体。
          对于使用O_APPEND打开的文件,每次write的时候,均会将file table中的当前文件偏移量赋值为v-node中的文件大小,强制每次的写入都会在文件的末尾写入。而每次操作如果修改了当前文件的长度时,则会更新全局v-node中的文件长度。

8.复制文件描述符,DUP
               int dup( int filedes ) ;  // 一个新的文件描述符将会被返回
               int dup2( int filedes , int filedes2 ) ; // 使用filedes2作为新的文件描述符,如果之前已经有文件打开,则先进行关闭
               文件结构图如下:
          APUE学习笔记 - Chapter 3. File I/O_第2张图片


9.改变文件的描述符:
               int fcntl( int filedes , int cmd , .. ) ; 
          这个函数通常有如下几个用途:
                    (1) 复制一个文件描述符: F_DUPFD
                    (2) Get/Set文件描述符的flag : F_GETFD , F_SETFD
                    (3) Get/Set文件状态flag : F_GETFL , F_SETFL
                    (4) Get/Set文件异步IO : F_GETTOWN , F_SETTOWN
                    (5) Get/Set record locks : F_GETLK , F_SETLK , F_SETLKW
           在修改flag的时候,必须先获取之前的状态,并且打开相关的flag,而不是直接set,这样有可能会关闭了之前打开的flag。
10.其他
           系统会为每个打开的文件描述符提供一个文件 /dev/fd/XX , 打开这样一个文件,相当于复制了该文件描述符。但打开的模式 基本上只是原来打开的模式的子集。

 

你可能感兴趣的:(File)