Linux文件操作符,各个文件调用接口

本文介绍了在Linux环境下使用C语言进行文件操作的方法,包括标准C库函数如fopen、fwrite等,以及系统调用接口如open、write等,并通过示例代码对比两种方法的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

目录

前言

C文件操作

Linux系统调用文件操作

    问题代码

   修改后的正确代码

系统调用接口

文件描述符为什么是int类型


前言

    在linux下操作文件可以用C语言那一套,使用fopen,fwrite,fread,fseek和fclose等函数即可完成基本文件操作,也可以用linux的系统调用接口:open、write、read、lseek和close

C文件操作

    c文件操作之前说过了,这次就直接把代码放到linux下运行:

 #include <stdio.h>
     #include <fcntl.h>
     #include <string.h>
     #include <stdlib.h>
     
     int main(){
     char* s="Linux is so easy!";
       int size=strlen(s);
       char buf[20]={0};
      FILE *fd=fopen("bite","wb+");
      if(fd==NULL){
        printf("fopen failed!");
        exit(-1);
      }
    
      fwrite(s,sizeof(char),size,fd);
      //fclose(fd);
    
      //FILE* fp=fopen("bite","wb+"); //再次打开  用fp(不同名称)
    
      fseek(fd,0,SEEK_SET);                                                                     
    
      fread(buf,sizeof(char),size,fd);
      printf("%s\n",buf);
      fclose(fd);
      printf("over\n");
      return 0;
    }

 

Linux系统调用文件操作

    系统调用接口相比于c文件操作的函数调用,每个函数名都少了开头的 f ,但实际上功能都基本相同,以下用代码示范(有些许问题)

    问题代码

 int main(){
    char *s="I love Linux sososososososo much!";
      int size=strlen(s);
      char buf[50]={0};
    
      int fd=open("./bite3",O_RDWR,0644);
      if(fd>0){
        printf("success!\n");
      }else{//  打开失败则进入下一步,需要重新打开
        printf("failed!\n");
        perror("open error:");
        printf("\n");
    
        printf("Accepting.Rerouted!\n");  //提示将再次打开
        printf("Alternatives_Opertion_Phoenix......Initiated!\n");
                                                                                                
        fd=open("./bite2",O_RDWR | O_CREAT | O_TRUNC);
        if(fd>0){  //再次打开成功则提示
          printf("Success!\n");
        }else{         //再次打开失败则提示
          printf("open failed!\n");
          perror("open error:");
        }
      }
    
      write(fd,s,size);
      lseek(fd,0,SEEK_SET);
    
      read(fd,buf,size);
      printf("ALready to read file:\n");
      printf("Contxt:%s",buf);
      printf("\n over \n");
      close(fd);
      return 0;
    }

    实际上上面代码在运行时一直出错,我查找了半天发现都是无法创建文件,系统报错说我没有相关权限,很奇怪,因为我换成fopen就可以运行,我试了很多办法也没用

    但意外的我重新再写一个程序,让那个新程序只执行open创建文件,然后创建好文件后再用上面的代码运行就可以了。(也就是说问题出在不存在文件时没有权限创建,但其实这不应该,有可能是我的电脑或是编译器有问题或者是用户权限不足)

   具体原因我也无法查询,总之错在第二次创建时没有权限,那我就修改一下代码,将其变成第一次创建就成功其实就可以运行了(之前的代码是我故意设计成第一次创建失败,需要创建第二次的)

   修改后的正确代码

    与上面唯一的不同就在第14行,保证了没有文件时创建文件

9 int main(){
W> 10   char *s="I love Linux sososososososo much!";
   11   int size=strlen(s);
   12   char buf[50]={0};
   13 
   14   int fd=open("./bite3",O_RDWR | O_CREAT | O_TRUNC,0644);  //直接创建成功
   15   if(fd>0){
   16     printf("success!\n");  //直接创建成功
   17   }else{  //因为一次就创建成功所以不会运行else里的代码
   18     printf("failed!\n");
   19     perror("open error:");
   20     printf("\n");
   21 
   22     printf("Accepting.Rerouted!\n");
   23     printf("Alternatives_Opertion_Phoenix......Initiated!\n");
   24 
   25     fd=open("./bite2",O_RDWR | O_CREAT | O_TRUNC,0664);   26       //因为一次就创建成功,也不需要创建第二次
   27     if(fd>0){
   28       printf("Success!\n");
   29     }else{
   30       perror("open error:");
   31     }
   32   }
   33   
   34   write(fd,s,size);
   35   lseek(fd,0,SEEK_SET);
   36                                                                                             
   37   read(fd,buf,size);                                                    
   38   printf("ALready to read file:\n");                                    
   39   printf("Contxt:%s",buf);                                              
   40   printf("\n over \n");                                                 
   41   close(fd);                                                            
   42   return 0;                                                             
   43 }  

系统调用接口

    ① open:    int open(char* pathname,int flag,int mode)

    open是不定参接口(参数个数不定),

    里面的flag是打开方式有三个必选项:O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(可读可写),这三个里面必选其中一个,注意如果要可读可以,不能写成 O_RDONLY | O_WRONLY 因为这三个符号在内存里其实是00000000(只读)、00000001(只写)、00000010(可读可写),所以O_RDONLY | O_WRONLY其实是00000000 | 00000001 =00000001,还是只写。

    flag可选项:O_CREAT(文件不存在时则创建)

                        O_TRUNC(截断文件,丢弃原数据)

                        O_APPEND(追加写入)

    例如 w+ 可以表示为: O_RDWR | O_CREAT | O_TRUNC

    open里的mode:当O_CREAT被使用时,就得设置mode,用于设置文件访问权限,例如0644(前面的0不能省略,会出现混乱)

    ②write:   ssize_t write(int fd,char* buf,size_t len)

     fd:open打开文件时返回的操作句柄(也叫文件描述符)

     buf: 要写入的文件地址

     len:要写入的数据长度

     write返回值:成功时返回实际写入长度,失败返回-1

    ③read:ssize_t read(int fd,char* buf, size_t len)

     fd:和write的一样

     buf:一块空间首地址,用于存放读入的数据

     len:要读的数据长度

    ④lseek:off_t lseek(int fd,off_t offset,int whence)

     fd:和前两个一样

     offset:偏移量

     whence:偏移的起始地址(只能是SEEK_SET、SEEK_CUR、SEEK_END三个中的一个)

     lseek的返回值可用于确定文件大小,lseek执行成功时,它会返回最终以文件起始位置为起点的偏移位置。如果出错,则返回-1,同时errno被设置为对应的错误值

    ⑤close:int close(int fd)

     fd:和前面的一样

文件描述符为什么是int类型

    fd(文件描述符),在进程中每打开一个文件,都会创建有相应的文件描述信息struct file,这个描述信息被添加在pcb的struct files_struct中,以数组的形式进行管理,随即向用户返回数组的下标作为文件描述符,用于操作文件。

    本来描述文件需要很多信息,这些信息都保存在一个结构体数组中,为了更方便描述一个文件,就直接采用这个信息结构体的数组下标来作为文件描述符。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值