文件描述符

  文件描述符的早期上限为20 , 现在增到 63; 其变化范围为 0 ~ OPEN_MAX

open函数

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

  filename  :  要打开文件的名字

  oflag     :  打开方式

          O_RDONLY 、 O_WRONLY 、O_RDWR 三个常量必须指定一个

          O_APPEND  、 O_CREAT  、O_EXCL 、O_TRUNC等是可选择的

          O_CREAT | O_EXCL 组和可用于判断文件是否存在,存在则打出错,否则创建新文件

/***********************************************
*function       : check if a file exist
*params         : @filename: pointer to the buffer
*return         : return -1 if exist or -1 if not
************************************************/
int             is_file_exist(const char* filename);

int             is_file_exist(const char* filename)
{
        int             fd;

        if(filename == NULL)
                return  0;
        fd = open(filename,O_RDONLY|O_EXCL|O_CREAT);
        if(fd != -1){

      close(fd);
                remove(filename);
                return  0;
        }
        return  1;
}


O_DSYNC  :等待每次write操作的完成 , 但是不等待文件属性的更新 , 除非影响到写操作的完成

O_RSYNC  :等待读操作的完成

O_SYNC   :等待每次写操作的完成并且同步更新文件属性

 

open() 返回的文件描述符值一定是最小未用描述符值。这一特点常被用来重定向标准文件描述符:具体做法是先调用close关闭标准描述符

(如 STDIN_FILENO),然后调用open函数,就可以在标准输入上打开新文件。

          creat(const char* filename , mode_t mode);  这个函数相当于 open(filename , O_RDWR|O_EXCL|O_CREAT, mode);

文件名和路径的截短

  当文件名超过 NAME_MAX 或路径长度超过 PATH_MAX的时候,根据系统不同,结果也不相同。

  可以测试 _POSIX_NO_TRUNC 宏

        #ifdef  _POSIX_NO_TRUNC

        if( (fd = open(filename,O_RDWR|O_EXCL|O_CREAT) == -1 && errno == ENAMETOOLONG){

          perror(filename);

        #endif

 

close 函数 

   关闭打开的文件

 

lseek函数

  设置打开文件的文件偏移量,默认情况下,打开一个文件时,除非O_APPEND标志被设置,否则文件偏移 为0

  该函数不能用于操作 管道、套接字、FIFO  ,  函数的返回值是先前的文件偏移量

  有些设备允许偏移量为 负 ,所以测试函数是否执行成功的时候  应该和 -1 比较 , 如果 ==-1 则失败  否则为成功

  lseek 仅仅调整内核中保存的文件结构的偏移量,不会引起任何I/O操作

  当文件偏移量大于文件长度的时候, lseek会在文件中形成文件空洞, 这些文件空洞不占用磁盘空间, 当 I/O 函数读写文件的时候,

  读到的空洞部分的字节的值为 0

 

read函数

  读到的字节数少于要求读取的字节数的原因

    读普通文件  :到达文件尾端

    读终端设备  :一次最多读取一行

    网络       :缓冲机构可能造成返回值小于要读取的字节数

    管道或FIFO  :管道中所包含的字节数少于要读取的字节数,则返回管道中实际的字节数

    由于信号造成中断

 

write函数

  返回实际写入的字节数

 

I/O效率

  在发生I/O操作的时候,一般缓冲区大小为 4096 的时候,I/O效率最高

  大多数的文件系统为改善I/O效率  , 一般采用某种  预读(read ahead)技术。 当检测到正在进行顺序读取的时候,系统会试图读取比

  要求的更多的数据,并假象应用程序很快会读取这些数据

 

文件共享

  不同进程中的文件描述符表中的描述符只想相同的文件节点,就实现了所谓的文件共享

 

原子操作

  原子操作要么不执行,要么一次执行完。

  不能被系统中断的操作。 当多进程对同一个文件进行写操作的时候,写操作应该 保证为原子 操作。可以用 pread  和 pwrite这两个原子操作函数

  来替代 read 和 write  , 这俩函数执行的时候无法被中断。而且  pread 不更新文件指针

  

三种复制现有文件描述符的方法

    1、int  dup(int fd) 函数

    2、int  dup2(int fd, int fd2);

          将 fd 复制为 指定的fd2 的描述符,如果fd2已经打开,则先关闭fd2

    3、int  fcntl(fd, F_DUPFD , fd2 )

 

冲洗缓冲区的三个函数

    void  sync(void)  :    将所有修改过的块排入写入队列 , 然后就返回, 不等待写入操作的结束

    int   fsync(int fd) :  仅仅对单一文件的缓冲区冲洗,但是会等待写入操作的完成,并且同步更新文件属性

    int   fdatasync(int fd) :  同 fsync()  , 但是不会更性文件属性,除非影响到写入操作

 

/dev/fd/

   当描述符 n 是打开的时候, 此时打开   “/dev/fd/n”  相当于复制  描述符 n 。

   但是打开后的权限不可更改  , 只能 是 描述度 n 的一个子集 。  

 

 

 

 

posted on 2013-05-29 21:52  wowk  阅读(234)  评论(0编辑  收藏  举报