[Linux C编程]文件操作

本文深入讲解了Linux系统下的文件操作,包括系统调用与库函数的使用,如创建、打开、读写文件的方法,并提供了丰富的代码示例。

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

文件操作

1. Linux系统调用及用户编程接口(API)

    所谓系统调用是指操作系统提供给用户的一组“特殊”接口,用户程序可以通过这组“特殊”接口来获得操作系统内核提供的的服务

为什么用户程序不能直接访问系统内核提供的服务呢?

 

由于在Linux中,为了更好地保护内核空间,将程序的运行空间分为内核空间和用户空间(也就是常称的内核态和用户态),它们分别运行在不同的级别上,在逻辑上是相互隔离的。

 

系统调用并不是直接与程序员进行交互的,它仅仅是一个通过软中断机制向内核提交请求,以获取内核服务的接口。在实际使用中程序员调用的通常是用户编程接口—API

1.函数的作用 2.函数的参数 3.函数的返回值

 

Linux 文件:

“一切皆为文件”——在Linux中对目录和设备的操作都等同于对文件的操作。

普通文件、目录文件、链接文件、设备文件

 

文件及文件描述符——fd

文件描述符是一个非负的整数,它是一个索引值,并指向在内核中每个进程打开文件的记录表。

 

系统调用——创建creat

函数的作用:创建一个文件

函数的原型:int creat(const char *pathname,mode_t mode);

文 件 头:#include <sys/types.h>

          #include <sys/stat.h>

          #include <fcntl.h>

返 回 值:成功:新的文件描述符

          出错:-1

mode:创建模式

S_IRUSR:可读

S_IWUSR:可写

S_IXUSR:可执行
    S_IXRWU:可读、可写、可执行

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.    
  4. #include <sys/types.h>  
  5. #include <sys/stat.h>  
  6. #include <fcntl.h>  
  7.    
  8. void  create_file(char *filename)  
  9. {  
  10.     if(creat(filename,0755)<0){  
  11.         printf("create file %s failure!\n",filename);  
  12.         exit(EXIT_FAILURE);  
  13.     }else{  
  14.         printf("create file %s success!\n",filename);  
  15.     }  
  16. }  
  17.    
  18. int main(int argc,char *argv[])  
  19. {  
  20.     int i;  
  21.        
  22.     if(argc<2)  
  23.     {  
  24.         perror("you haven't input the filename,please try again!\n");  
  25.         exit(EXIT_FAILURE);  
  26.     }  
  27.    
  28.     for(i=1;i<argc;i++)  
  29.     {  
  30.         create_file(argv[i]);      
  31.     }  
  32.    
  33.     exit(EXIT_SUCCESS);  
  34. }  


 

系统调用——打开open

函数的作用:打开一个文件;

函数的原型:int  open(const char *pahtname, int flags);

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

返 回 值:文件描述符---成功;出错:-1;

flags:

参数:

O_RDONLY:  只读

 O_WRONLY:  只写

O_RDWR:  可读可写

        O_CREAT:  如果原来这个文件不存在,那么有这个参数就可以创建这个文件;

        O_APPEND: 原来有内容,则会自动保留文件内容,自动向下读写;

        O_TRUNC:  文件存在,有内容,文件清空;

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.    
  4. #include <sys/types.h>  
  5. #include <sys/stat.h>  
  6. #include <fcntl.h>  
  7.    
  8. int main(int argc ,char *argv[])  
  9. {  
  10.     int fd;  
  11.       
  12.     if(argc<2)  
  13.     {  
  14.         puts("please input the open file pathname!\n");  
  15.         exit(1);  
  16.     }  
  17.       
  18.     //如果flag参数里有O_CREAT表示,该文件如果不存在,系统则会创建该文件,该文件的权限由第三个参数决定,此处为0755  
  19.     //如果flah参数里没有O_CREAT参数,则第三个参数不起作用.此时,如果要打开的文件不存在,则会报错.  
  20.     //所以fd=open(argv[1],O_RDWR),仅仅只是打开指定文件  
  21.     if((fd=open(argv[1],O_CREAT|O_RDWR,0755))<0)  
  22.     {  
  23.         perror("open file failure!\n");  
  24.         exit(1);  
  25.     }else{  
  26.         printf("open file %d  success!\n",fd);  
  27.    
  28.     }  
  29.     close(fd);  
  30.     exit(0);  
  31.       
  32. }     


 

 系统调用——读read

 函数的作用: 从打开的文件中读取数据

 函数的原型:ssize_t  read(int fd, void *buf,  size_t count);

 头 文 件: #include  <unistd.h>

 返 回 值:正常是实际读到的字节数;

           如果是在文件结束或者是无数据,返回0;

           出错,-1;

 

 系统调用——写write

 函数的作用: 向打开的文件中写数据

 函数的原型: ssize_t   write(int fd, const void *buf, size_t count);

 头 文 件:  #include <unistd.h>  

 返 回 值:  成功会返回实际写入的字节数;

             出错:-1;

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <sys/types.h>  
  3. #include <sys/stat.h>  
  4. #include <fcntl.h>  
  5. #include <unistd.h>  
  6. #include <string.h>  
  7.    
  8. #define LENGTH 100  
  9.    
  10. int main()  
  11. {  
  12.     int fd;  
  13.     int len;  
  14.    
  15.     char str[LENGTH];  
  16.    
  17.     fd = open("hello.txt",O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);  
  18.    
  19.     if(fd > 0)  
  20.     {  
  21.         write(fd,"Hello,Software weekly",strlen("Hello,Software weekly"));  
  22. //close(fd);  
  23.     }  
  24.       
  25.     fd = lseek(fd,0,SEEK_SET);  
  26.     fd = open("hello.txt",O_RDWR);  
  27.       
  28.     len = read(fd,str,LENGTH);  
  29.     str[len] = '\0';  
  30.    
  31.     printf("read length is %d\n",len);  
  32.     printf("%s\n",str);  
  33.    
  34.     close(fd);  
  35.    
  36.     return 0;  
  37. }           


 

系统调用——定位lseek

函数的功能:进行文件定位

函数的原型: int lseek(int fd, offset_t  offset, int whence);

函数的参数:fd:

            offset: 指针的微调,在指定的指针向前移动为负, 向后为正;

            whence:  SEEK_SET:放在文件头

             SEEK_CUR:当前的位置;

             SEEK_END:  文件尾;

            

返 回 值:返回文件当前指针到文件开始的地方有多少字节;

   出错-1;

  

示例:拷贝函数:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <sys/types.h>  
  2. #include <sys/stat.h>  
  3. #include <stdio.h>  
  4. #include <fcntl.h>  
  5. #include <errno.h>  
  6.    
  7. #define BUFFER_SIZE 1024  
  8.    
  9. int main(int argc, char *argv[])  
  10. {  
  11.     int write_fd;    
  12.     int read_fd;     
  13.    
  14.     int write_byte;      
  15.     int read_byte;       
  16.    
  17.     char buffer[BUFFER_SIZE];  
  18.     char *ptr;  
  19.    
  20.     if(argc != 3)  
  21.     {  
  22.         printf("Please try again,the number of para is less than 3!\n");  
  23.     }  
  24.    
  25.     if((read_fd = open(argv[1],O_RDONLY)) == -1)  
  26.     {  
  27.         printf("read_fd open failure!\n");  
  28.     }  
  29.    
  30.     if((write_fd = open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR)) == -1)  
  31.     {  
  32.         printf("write_fd open failure!\n");  
  33.     }  
  34.    
  35.     while(read_byte = read(read_fd,buffer,BUFFER_SIZE))    
  36.     {  
  37.         if((read_byte == -1)&&(errno != EINTR))    
  38.         {  
  39.             break;  
  40.         }  
  41.         else if(read_byte > 0)  
  42.         {  
  43.             ptr = buffer;     
  44.               
  45.             while(write_byte = write(write_fd,ptr,read_byte))    
  46.             {  
  47.                 if((write_byte == -1)&&(errno != EINTR))  
  48.                 {  
  49.                     break;  
  50.                 }  
  51.                 else if(write_byte == read_byte)    
  52.                 {  
  53.                     break;  
  54.                 }  
  55.                 else if(write_byte > 0)    
  56.                 {  
  57.                     ptr += write_byte;  
  58.                     read_byte -write_byte;  
  59.                 }  
  60.             }  
  61.             if(write_byte == -1)  
  62.             {  
  63.                 break;  
  64.             }  
  65.         }  
  66.     }  
  67.    
  68.     close(read_fd);  
  69.     close(write_fd);  
  70.       
  71.     return 0;  
  72. }  


标准库函数

·不带缓存的I/O对是文件描述符操作,带缓存的I/O是针对流的。

·标准I/O库就是带缓存的I/O,它由ANSI C标准说明。当然,标准I/O最终都会调用上

  面的I/O例程。

·标准I/O库代替用户处理很多细节,比如缓存分配、以优化长度执行I/O等。

它提供了三种类型的缓存:
1) 全缓存。当填满标准I/O缓存后才执行I/O操作。磁盘上的文件通常是全缓存的。
2) 行缓存。当输入输出遇到新行符或缓存满时,才由标准I/O库执行实际I/O操作。stdin、

   stdout通常是行缓存的。
3) 无缓存。相当于read、write了。stderr通常是无缓存的,因为它必须尽快输出。

 

库函数——打开fopen

函数的作用: 打开文件

函数的原型: FILE *fopen(const char *pth, const char *mode)

 mode:

   r:读,文件必须存在;

   r+:打开可读写,文件必须存在;

   w:打开只写文件,文件不存在就会创建文件; 文件清0;

   w+:打开可读写的文件,

   a:附加的形式打开只写文件,不存在就创建,存在就写到原来的文件尾。

   a+:以附加的形式打开可读写的文件,不存在就创建,存在就写到原来的文件尾。

   b:二进制文件

文 件 头: #include <stdio.h>      #include  "  "

返 回 值:  成功是指向=文件流的指针;

            出错返回NULL;     

 

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. int main()  
  3. {  
  4. FILE * fp;  
  5. fp = fopen(“hello.c”,“r+”);  
  6. if(fp != NULL)  
  7. {  
  8.     printf(“fopen is ok!\n”);  
  9. }  
  10. fclose(fp);  
  11.     return 0;  
  12. }  
  13.    


 库函数——字符写fputc

 函数的作用:  将一个指定的字符写入到文件流中;

 函数的原型:  int fputc(int c, FILE *stream);

 返 回 值:   返回写入成功的字符,c;  EOF则表示失败。

 

 库函数——字符读fgetc

 函数的作用:从文件流中读取一个字符

 函数原型: int fgetc(FILE *stream)

 返 回 值:返回值正常的是读取的字符;EOF表示到了文件尾;

 

库函数——字符串写fputs

函数的作用:将一个字符串写入到文件内

函数的原型: int fputs(const char *s, FILE *stream)

返 回 值:成功返回写成字符数; EOF表示出错

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #define LENGTH 100  
  3. main()  
  4. {  
  5. FILE *fd;  
  6. char str[LENGTH];  
  7.    
  8. fd = fopen("hello.txt", "w+"); /* 创建并打开文件 */  
  9. if (fd)  
  10. {  
  11. fputs("Hello, Software Weekly", fd); /* 写入Hello, software weekly字符串 */  
  12. fclose(fd);  
  13. }  
  14.    
  15. fd = fopen("hello.txt", "r");  
  16. fgets(str, LENGTH, fd); /* 读取文件内容 */  
  17. printf("%s\n", str);  
  18. fclose(fd);  
  19. }  


 

 库函数——字符串读fgets

 函数的作用:从文件中读取一个字符串;

 函数的原型: char *fgets(char *s, int size,  FILE *steam)

 函数的参数:从stream中读size-1个字符到s中

 返 回 值: 成功返回s, 出错NULL。

 

库函数——数据块读 fread

函数的作用:从文件流中读取数据块

函数原型:  size_t  fread(void *ptr,  size_t size, size_t  nmemb, FILE * stream);

返 回 值: 返回实际读到数据块的数目

           比nmember小的话,可能是到了文件尾,或者错误发生。

           feof :到文件尾;

           ferror:判断错误的

库函数——数据块写fwrite

函数的作用: 将数据块写到文件流中:

函数原型:  size_t  fwrite(const void * ptr,  size_t size,  size_t nmemb,  FILE *stream);

返回值: 实际写入的nmemb数目;

 

库函数——fseek

函数的作用:移动文件流的读写位置

函数的原型: int fseek(FILE * stream, long offset, int whence)

返 回 值:成功返回0, 出错-1;

****使用ftell来获取当前的位置;

 

库函数——ftell

函数的作用:读取文件流的读写位置;

函数的原型:long ftell(FILE * stream)

返回值: 成功返回当前的读写位置;

         出错-1;

         

库函数——feof

函数的作用: 检测文件流是否到了文件尾

函数的原型:int feof(FILE *steam)

返回值:  非零代表到了文件尾,其他是0;

 

库函数——格式化读fprintf

函数的作用:格式化数据到文件

函数的原型: int fprintf(FILE *stream, const char *format, ....);

返回值:成功返回实际输入的字符数,失败-1;

 

库函数——格式化写fscanf

函数的作用: 格式化字符串输入

函数的原型: int fscanf(FILE *strem, const char *fromat,....)

返回值:成功返回参数数目,出错-1

 

用库函数实现file_cp.c

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <string.h>  
  2. #include <string.h>  
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5.    
  6. #define BUFFER_SIZE 1024  
  7.    
  8. int main(int argc,char **argv)  
  9. {  
  10. FILE *from_fd;  
  11. FILE *to_fd;  
  12. long file_len=0;  
  13. char buffer[BUFFER_SIZE];  
  14. char *ptr;  
  15. /*判断入参*/  
  16. if(argc!=3)  
  17. {  
  18. printf("Usage:%s fromfile tofile\n",argv[0]);  
  19. exit(1);  
  20. }  
  21.    
  22. /* 打开源文件 */  
  23. if((from_fd=fopen(argv[1],"rb"))==NULL)  
  24. {  
  25. printf("Open %s Error\n",argv[1]);  
  26. exit(1);  
  27. }  
  28.    
  29. /* 创建目的文件 */  
  30. if((to_fd=fopen(argv[2],"wb"))==NULL)  
  31. {  
  32. printf("Open %s Error\n",argv[2]);  
  33. exit(1);  
  34. }  
  35.    
  36. /*测得文件大小*/  
  37. fseek(from_fd,0L,SEEK_END);  
  38. file_len=ftell(from_fd);  
  39. fseek(from_fd,0L,SEEK_SET);  
  40. printf("from file size is=%d\n",file_len);  
  41.    
  42. /*进行文件拷贝*/  
  43. while(!feof(from_fd))  
  44. {  
  45. fread(buffer,BUFFER_SIZE,1,from_fd);  
  46. if(BUFFER_SIZE>=file_len)  
  47. {  
  48. fwrite(buffer,file_len,1,to_fd);  
  49. }  
  50. else  
  51. {  
  52. fwrite(buffer,BUFFER_SIZE,1,to_fd);  
  53. file_len=file_len-BUFFER_SIZE;  
  54. }  
  55. memset(buffer, 0, BUFFER_SIZE);  
  56. //bzero(buffer,BUFFER_SIZE); //清零  
  57. }  
  58. fclose(from_fd);  
  59. fclose(to_fd);  
  60. exit(0);  
  61. }  
  62.    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值