Linux环境编程--文件描述符的使用以及常用来搭配的几个函数实例

一.文件描述符

    对于内核而言,所有打开的文件、设备、网络socket都是通过文件描述符引用,文件描述符是一个非负整数。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。当读、写一个文件时,使用open或creat返回的文件描述符表示该文件,将其作为参数床给read或write。
    应用程序运行的时候,系统将会为该进程默认打开三个文件描述符:
    标准输入:STDIN_FILENO (0)
    标准输出:STDOUT_FILENO (1)
    标准出错:STDERR_FILENO (2)
    文件描述符的变化范围是:0~OPEN_MAX-1 (OPEN_MAX-1这边可以修改)

Linux环境编程--文件描述符的使用以及常用来搭配的几个函数实例 

注:write()是系统调用函数,不需要头文件,1表示标准输出(屏幕)

 

二.函数open()

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

    返回值int fd 文件描述符,open系统调用返回的文件描述一定是最小的未使用的文件描述符值。

 

    注:fd = open("test.log",O_RDWR|O_CREAT|O_TRUNC,0644);    //在没有test.log的情况下读写它,并且将内容清除,给予权限644。此时,open返回的最小值就是标准输出

 

参数说明:

 

 

Linux环境编程--文件描述符的使用以及常用来搭配的几个函数实例

三.函数close()

    该函数用来关闭一个打开的文件,关闭一个文件时还会释放该进程在该文件上的所有记录锁。当一个进程终止时,内核自动关闭它所有打开的文件。

    int close(int fd);

注:标准输出重定向:

    1.close(1);    //表示将标准输出到屏幕这条路径关闭(系统默认1指定为屏幕),但是不意味着标准输出被关闭。

 

 

四.函数creat()

 

 

    等价于open(path,O_WRONLY|O_CREAT|O_TRUNC, mode);

五.函数lseek()

    每打开一个文件时都有一个与其关联的“当前文件偏移量”。它通常是一个非负整数,用以度量从文件开始处计算的字节数。通常读写操作都是从当前文件偏移量处开始,并使用偏移量增加所读写的字节数。

    按系统默认的情况,当打开一个文件时,除非指定O_APPEND选项,否则该偏移量被设置为0.

    例子:lseek(fd,0,SEEK_SET);表示从文件开头往后0处读取.

六.函数read()/write()

    read()函数用来从打开的文件中读取数据:

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

    如read成功,则返回读到的字节数。如已到达文件的尾端,则返回0。

    write()函数用来往打开的文件中写入数据:

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

    如write成功,则返回实际写入的字节数,失败返回-1。

    例子:
Linux环境编程--文件描述符的使用以及常用来搭配的几个函数实例
    其输出结果为:
Linux环境编程--文件描述符的使用以及常用来搭配的几个函数实例

 

原因:

 

    1.从数据的方向去理解,buf是局部变量在栈中,所以是一个随机值,因此在使用buf之前要用memset(buf,0,sizeof(buf))进行清零。

        2.处理后还没有解决,那是因为文件有一个偏移量,buf此时读的是光标处(EOF),二光标处默认在你所写的文字之后,所以还需要设置读取时光标的位置lseek(fd,0,SEEK_SET)表示从开头读取到EOF。还有lseek要放在read之前否则就跟没有设置一样。

总结:

1.每次使用buf时,一定要紧跟memset的设置

2.考虑是否需要修改文件偏移量,一般是读取文件都是需要修改

 

修改之后的代码:

Linux环境编程--文件描述符的使用以及常用来搭配的几个函数实例

结果如下:

Linux环境编程--文件描述符的使用以及常用来搭配的几个函数实例

 

九.函数dup()\dup2()

    以下两个函数都可以用来复制一个现有的文件描述符。

    int  dup(int  fd);

    int dup2(int fd, int fd2);

   由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。

   dup2可以用fd2参数指定新描述符的值。如果fd2已经打开,则先关闭。如fd等于fd2, 则dup2返回fd2, 而不关闭它。

  使用这两个函数可以用来实现标注输入、标准输出、标准出错重定向:

     int     fd = -1;

     fd = open(“std.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666);

     dup2(fd, STDIN_FILENO);

     dup2(fd, STDOUT_FILENO);

     dup2(fd, STDERR_FILENO);

    

     printf(“Hello Word!\n”);

注:dup2()就等价于之前的先close(1)然后open(fd,..),dup2更方便

十.ioctl()

    ioctl()函数一直是I/O操作的杂物箱,不能用本章中其他函数表示的I/O操作通常都能用ioctl()表示。终端I/O、设备I/O是使用ioctl()最多的地方。

    int  ioctl(int  fd,  int cmd,  ...);

    fd:  文件描述符

    cmd:  命令字,这个参数需要与设备驱动中的cmd保持一致。

第三个参数可选

 例子:

  int     fd = -1;

  fd = open(“/dev/led”, O_RDWR);

  ioctl(fd, TURN_OFF,  3);

  close(fd);