• 文件I/O(二)


    (6)lseek

    lseek和标准I/O库的fseek函数类似,可以移动当前读写位置(或者叫偏移量)

       #include <sys/types.h>
       #include <unistd.h>

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

    参数:

     fd 表示要操作的文件描述符

    offset是相对于whence(基准)的偏移量

    whence 可以是SEEK_SET(文件指针开始),SEEK_CUR(文件指针当前位置) ,SEEK_END为文件指针尾

    返回值:文件读写指针距文件开头的字节大小,出错,返回-1

    lseek 主要作用是移动文件读写指针,因此还有以下两个作用

    1.拓展文件,不过一定要一次写的操作。迅雷等下载工具在下载文件时候先扩展一个空间,然后再下载的。

    #include<sys/stat.h>
    #include<fcntl.h>
    #include<unistd.h>
    #include<errno.h>
    #include<stdlib.h>
    int main()
    {
       int fd=open("abc",O_RDWR);
       if(fd<0)
       {
                 perror("open abc");
                 exit(-1);
       }
       //扩展一个文件,一定要有一次写操作
       lseek(fd,ox1000,SEEK_SET);
       write(fd,“a”,1);
       close(fd);
       return 0;
    }

    注:看一个文件里边的内容 od -tcx 文件名

    2.获取文件大小

    利用返回值:文件读写指针距文件开头的字节大小,出错,返回-1

    fd=open("hello",O_RDWR);
    if(fd<0)
    {
         perror("open hello");
         exit(-1);
    }
    printf("hello size=%d
    ",lseek(fd,0,SEEK_END));
    close(fd);

    3.移动读写指针的位置

    (7)fcntl

     获取或设置文件的访问控制属性

    功能描述:根据文件描述词来操作文件的特性。

    #include <unistd.h>
    #include <fcntl.h> 
    int fcntl(int fd, int cmd); 
    int fcntl(int fd, int cmd, long arg); 
    int fcntl(int fd, int cmd, struct flock *lock);

    fcntl()针对(文件)描述符提供控制。参数fd是被参数cmd操作(如下面的描述)的描述符。针对cmd的值,fcntl能够接受第三个参数int arg。

    [返回值]
    fcntl()的返回值与命令有关。如果出错,所有命令都返回-1,如果成功则返回某个其他值。下列三个命令有特定返回值:F_DUPFD , F_GETFD , F_GETFL以及F_GETOWN。
        F_DUPFD   返回新的文件描述符
        F_GETFD   返回相应标志
        F_GETFL , F_GETOWN   返回一个正的进程ID或负的进程组ID

        F_SETFD  

    fcntl函数有5种功能: 
    1. 复制一个现有的描述符(cmd=F_DUPFD). 
    2. 获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD). 
    3. 获得/设置文件状态标记(cmd=F_GETFL或F_SETFL). 
    4. 获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN). 
    5. 获得/设置记录锁(cmd=F_GETLK , F_SETLK或F_SETLKW).

    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <string.h>
    #include <stdlib.h>
    #define MSG_TRY "try again
    "
    int main(void)
    {
       char buf[10];
       int n;
       int flags;
      flags = fcntl(STDIN_FILENO, F_GETFL);//获取一个文件的访问控制属性
      flags |= O_NONBLOCK;
      if (fcntl(STDIN_FILENO, F_SETFL, flags) == -1)//设置  
      {
        perror("fcntl");
        exit(1);
      }
     tryagain:
      n = read(STDIN_FILENO, buf, 10);
      if (n < 0) 
      {
        if (errno == EAGAIN)
        {
          sleep(1);
          write(STDOUT_FILENO, MSG_TRY,strlen(MSG_TRY));
          goto tryagain;
        }
        perror("read stdin");
        exit(1);
      }
      write(STDOUT_FILENO, buf, n);
      return 0;
    }

          fcntl

    (8)ioctl

    ioctl用于向设备发控制和配置命令大部分驱动,除了需要具备读写设备的能力之外,还需要具备对硬件控制的能力。

    #include<sys/ioctl.h>
    
    int ioctl(int d,int request,...);

    其中d就是用户程序打开设备时使用open函数返回的文件描述符,request就是用户程序对设备的控制命令,至于后面的省略号,则是一些补充参数,一般最多一个,有或没有是和request的意义相关的,详情请参考man 2 ioctl_list以了解更多。ioctl函数是文件结构中的一个属性分量,就是说如果驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道或其它一些自己想要控制且设备支持的功能。

    fcntl 共性,ioctl个性

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/ioctl.h>
    
    int main(void)
    
    {
          struct winsize size;//winsize指定终端文件的大小
          if(isatty(STDOUT_FILENO==0)//判断是否为终端文件,大于0是,==0不是
              exit(1);
          if(ioctl(STDOUT_FILENO,TIOCGWINSZ,&size)<0)//获取终端窗口大小存入到size
          {
                 perror("ioctl TIOCGWINSZ error");
                 exit(1);
            }
           printf(%d rows,%d columns
    ",size.ws_row,size.ws_col);
           return 0;
    }

    在图形界面的终端里多次改变终端窗口大小并运行该程序,观察结果。

     

  • 相关阅读:
    gdbinit理解
    debug套路
    node 版本升级
    工作方式
    vscode 插件编写
    函数闭包与装饰器
    高阶函数与递归
    函数嵌套及作用域
    函数
    文件处理
  • 原文地址:https://www.cnblogs.com/rainbow1122/p/7804337.html
Copyright © 2020-2023  润新知