文件I/O

Posted rainbow1122

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件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\\n",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\\n"
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\\n",size.ws_row,size.ws_col);
       return 0;
}

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

 

以上是关于文件I/O的主要内容,如果未能解决你的问题,请参考以下文章

java I/O流基础(知识+代码示例)

对文件 I/O,标准 I/O 的缓冲的理解

监控文件描述符的六种方式(进程监控selectpoll非阻塞轮询I/O异步I/O线程监控)

asyncio 是不是支持文件操作的异步 I/O?

Scala 文件 I/O

Linux I/O重定向