Linux 文件I/O

文件I/O

快速对齐

  1. Esc//进入命令模式
  2. GG//回到起始位置
  3. v//进入可是模式
  4. shift+g//全选
  5. =//快速对齐

sscanf & sprintf

  • int sscanf(const char *str, const char *format, …);

    int sprintf(char *str, const char *format, …);

  • 功能:按format格式对str指向的字符数组进行I/O操作
  • 返回:成功返回I/O的字节数,失败返回EOF
#include<stido.h>
int main(void)
{
  double a = 0.0;
  char b[20] = " ";
  int c = 0;
  char q[20] = " ";
  char *p = "12.2 张三 24";
  sscanf(p,"%f %s %d",&a,b,&c);
  sprintf(q,"%f %s %d",a,b,c);
  printf("%.2f,%s,%d\n",a,b,c);
  return 0;    
}

I/O 系统调用

  • 全缓存
    • 磁盘文件
      • 全缓存满了
      • fflush
  • 行缓存
    • 标准输入输出
      • 行缓存满了
      • ‘\n’
      • fflush
  • 无缓存
    • 标准错误流
      • perror

文件常用系统调用

  • open()

    • int open(const char *pathname, int flags);

    int open(const char *pathname, int flags, mode_t mode);

    • 功能:打开或创建一个文件
    • 返回:成功返回文件描述符,失败返回-1
    • open函数的flags参数,O_RDONLY、O_WRONLY或O_RDWR 与多个可选模式按位或操作
    • O_RDONLY:以只读方式打开
    • O_WRONLY:以只写方式打开
    • O_RDWR :以读写方式打开
    • O_APPEND:文件以追加模式打开在写以前,文件读写指针被置在文件的末尾
    • O_CREAT:若文件不存在将创建一个新文件.新文件的权限由mode决定,例:0765
    • O_EXCL :通过O_CREAT,生成文件 , 若文件已经存在,则open出错,调用失败.若是存在符号联接,将会把它的联接指针的指向文件忽略.
    • O_TRUNC:假如文件已经存在,且是一个普通文件,打开模式又是可写,就把文件的长度设置为零,丢弃其中的现有内容.若文件是一个FIFO或终端设备文件,O_TRUNC标志被忽略
    • O_DIRECTORY:假如pathname不是目录, 打开就失败
    • O_NONBLOCK 或 O_NDELAY:打开(open) 文件可以以非块(non-blocking) 模式打开.此时文件并没有打开,也不能使用返回的文件描述符进行后续操作,而是使调用程序等待
  • create()
    • int creat(const char *pathname, mode_t mode);
    • 功能:创建一个新的文件,
    • 返回:成功返回描述符并以只读方式打开文件,失败返回-1
  • close()
    • int close(int fd);
    • 功能:关闭一个打开的文件
    • 返回:若成功为0 ,若出错为-1
  • read()
    • ssize_t read(int fd, void *buf, size_t count);
    • 功能:从打开文件中读数据
    • 返回:读到的字节数,若已到文件尾为0 ,若出错为-1
  • write()
    • ssize_t write(int fd, const void *buf, size_t count);
    • 功能: 向打开的文件中写数据
    • 返回:若成功为已写的字节数,若出错为-1
  • lseek()
    • off_t lseek(int fd, off_t offset, int whence);
    • 功能:定位一个已打开的文件
    • 返回:若成功则返回新的文件位移量( 绝对偏移量) ,若出错为-1
  • fcntl()
    • int fcntl(int fd, int cmd);
      int fcntl(int fd, int cmd, long arg);
      int fcntl(int fd, int cmd, struct flock *lock);
    • 功能:可以改变已经打开文件的性质
    • 复制一个现存的描述符, 新文件描述符作为函数值返(cmd=F_DUPFD)
    • 获得/设置文件描述符标志(cmd= F_GETFD或F_SETFD)
    • 获得/设置文件状态标志(cmd = F_GETFL或F_SETFL)
    • 获得/设置文件锁(cmd = F_SETLK、cmd = F_GETLK、 F_SETLKW)
      • 第三个参数为struct flock结构体
    • 返回:若成功则依赖于cmd ,若出错为-1
    • cmd的常见取值
    • F_DUPFD:复制文件描述符,新的文件描述符作为函数返回值返回
    • F_GETFD/F_SETFD:获取/设置文件描述符,通过第三个参数设置
    • F_GETFL/F_SETFL:获取/设置文件状态标志,通过第三个参数设置。
      可以更改的几个标志是:O_APPEND, O_NONBLOCK, SYNC,
      O_ASYNC(O_RDONLY、O_WRONLY和O_RDWR不适用)
  • fdopen()
    • FILE *fdopen(int fd, const char *mode);
    • 功能:文件描述符=> 文件指针(fd=>FILE*)
  • fileno()
    • int fileno(FILE *stream);
    • 功能:文件指针=> 文件描述符(FILE*=>fd)
  • 标准文件指针
    • stdin -》0
    • stdout -》 1
    • stderr -》2

设置缓存setbuf & setvbuf

  • setbuf
    • void setbuf(FILE *stream, char *buf);
    • 功能:流缓冲操作,setbuf 总是使用非最优的缓冲大小,应当避免使用它。
    • 返回:无
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(void)
{
    setbuf(stdout,NULL);
    int i = 0;
    for(i=0 ; i < 100 ; ++i){
        printf("*");
    }
    return 0;
}
  • setvbuf
    • int setvbuf(FILE *stream, char *buf, int mode , size_t size);
    • 功能:可以用在任何打开的流上,改变它的缓冲。参数 mode 必须是下列三个宏之一:
    • _IONBF 无缓冲
    • _IOLBF 行缓冲
    • _IOFBF 完全缓冲
    • 返回:成功返回0,失败返回任何值
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(void)
{
  char buffer[1024] = " ";
  if(setvbuf(stdout,buffer,_IONBF,1024) != 0){
    printf("%s",strerror(errno));
  }
  int i = 0;
  for(i=0 ; i < 100 ; ++i){
    printf("*");
  }
  return 0;
}

open函数示例

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
    if (argc < 3){
        perror("输入的参数错误!");
        exit(1);
    }
    int fp1 = open(argv[1],O_RDWR | O_CREAT, 0765);
    int fp2 = open(argv[2],O_RDWR | O_CREAT, 0765);
    if(fp1 < 0 || fp2 < 0){
        printf("%s",strerror(errno));
        exit(1);
    }
    printf("fp1:%d,fp2:%d",fp1,fp2);
    close(fp1);
    close(fp2);
    return 0;
}

用系统调用函数read & write 实现 cp

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
    if (argc < 3){
        perror("输入的参数错误!");
        exit(1);
    }
    int fp1 = open(argv[1],O_RDWR);
    int fp2 = open(argv[2],O_RDWR | O_CREAT, 0765);
    if(fp1 < 0 || fp2 < 0){
        printf("%s",strerror(errno));
        exit(1);
    }
    char buffer[1024] = " ";
    while(1){
        int fpr = read(fp1,buffer,1024);
        if(fpr == 0){
          break;
        }
        write(fp2,buffer,sizeof(buffer));
        memset(buffer,0,sizeof(buffer));
    }
    close(fp1);
    close(fp2);
    printf("已经将文件%s复制到文件%s中.\n",argv[1],argv[2]);
    return 0;
}

运用dup和dup2

  • int dup(int oldfd);
    int dup2(int oldfd, int newfd);
    • oldfd:原先的文件描述符newfd:新的文件描述符
    • 功能:文件描述符的复制,由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。用dup2则可以用newfd参数指定新描述符的数值。如果newfd已经打开,则先将其关闭。如若oldfd等于newfd,则dup2返回newfd,而不关闭它。
    • 返回:成功返回新文件描述符, 出错返回-1
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
    if (argc < 3){
        perror("输入的参数错误!");
        exit(1);
    }
    int fp1 = open(argv[1],O_WRONLY | O_CREAT | O_TRUNC, 0765);
    int fp2 = open(argv[2],O_WRONLY | O_CREAT | O_TRUNC, 0765);
    if(fp1 < 0 || fp2 < 0){
        printf("%s",strerror(errno));
        exit(1);
    }
    int save_fd = dup(1);
    dup2(fp1,1);
    char *p = "abcdefg";
    write(1,p,strlen(p));
    dup2(fp2,1);
    char *q = "123456";
    write(1,q,strlen(q));
    dup2(save_fd,1);
    char *r = "ok";
    write(1,r,strlen(r));
    close(fp1);
    close(fp2);
    puts("");
    return 0;
}

fdopen的应用

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int cmp(const void *a,const void *b){
  return (*(int *)a > *(int *)b);
}
int main(int argc,char *argv[])
{
  if (argc < 3){
    perror("输入的参数错误!");
    exit(1);
  }
  int fp1 = open(argv[1],O_RDONLY);
  int fp2 = open(argv[2],O_WRONLY | O_CREAT | O_TRUNC, 0765);
  if(fp1 < 0 || fp2 < 0){
    printf("%s",strerror(errno));
    exit(1);
  }
  FILE* fp = fdopen(fd1,"r");
  if(fp == NULL){
    printf("%s\n",strerror(errno));
    exit(-1);
  }
  char buffer[1024] = " ";
  int *p = NULL;
  int len = 0,i = 0;
  while(fgets(buffer,1024,fp) == NULL){
    p = realloc(p,(length+1)*sizeof(int));
    p[len++] = atoi(buffer);
    memset(buffer,0,sizeof(buffer));
  }
  qsort(p,len,sizeof(p[0]),cmp);
  memset(buffer,0,sizeof(buffer));
  for(i=0 ; i < len ; ++i){
    sprintf(buffer,"%d\n",p[i]);
    write(fd2,buffer,strlen(buffer));
  }
  free(p);
  p = NULL;
  fclose(fp);
  fp = NULL;
  close(fp1);
  close(fp2);
  return 0;
}

fcntl函数示例

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(void)
{
    int fd = open("1.txt",O_WRONLY | O_CREAT | O_APPEND,0765);
    if(fd < 0){
        perror("open file fail");
        exit(1);
    }
    int fdF = fcntl(fd,F_GETFL);
    fdF &= ~O_APPEND;
    fcntl(fd,F_SETFL,fdF);
    write(fd,"write ok!\n",strlen("write ok!\n"));
    printf("fd :%#o\n",fd);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值