当前位置:   article > 正文

Linux文件编程_o_rdwr

o_rdwr

在windows中手动修改文件操作步骤:打开\创建文档,编辑文档,保存文档,关闭文档。在Linux中就是用代码操作文件使计算机自动化完成以上步骤。

Linux为此提供了一系列API,打开\创建文件:open,读写:write\read,光标定位:lseek,关闭:close

文件的打开

  1. 需要包含的头文件:使用man查询open,可以看到要使用open必须包含3个头文件,分别是:<sys/types.h>,<sys/stat.h>,<fcntl.h>

  1. 返回值:open函数有整数返回值,返回文件的文件描述符,用来区分不同的文件,相当于文件的索引。当文件打开成功时,返回的是非负整数,打开失败时返回负数

  1. 参数含义:

pathname:要打开的文件名(含路径,缺省位当前路径)

flags:打开方式,有三种方式,分别是O_RDONLY只读打开, O_WRONLY只写打开, O_RDWR 可读可写打开。

当附带了权限后,打开的文件就只能按照这种权限来操作,比如,我使用O_RDONLY打开文件之后,我不能对文件进行写操作,我只能读

以上3个参数中应当只指定一个,下列的参数是可以选择的:

  1. O-CREAT 若文件不存在则创建它。使用此选项是,需要同时说明第三个参数mode,用其说明该新文件的存取许可权限

  1. O_EXCL 如果同时制定了OCREAT,而文件已经存在,则返回-1

  1. O_APPEND 每次写时都加到文件的尾端

  1. O_TRUNC 若文件种本来有内容,而且位只读或只写成功打开,则将其长度截短为0

mode:一定是再flags中使用了O_CREAT标志,mode记录待创建的文件的访问权限。

  1. 作用:打开一个文件,并返回该文件的文件描述符,以便于对其进行读写等操作

  1. 相关应用

  1. //打开当面目录下的file1文件
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. int main()
  7. {
  8. int fd;
  9. fd=open("./file1",O_RDWR);
  10. printf("fd=%d\n",fd);
  11. return 0;
  12. }

创建file1,使用可读可写的方式打开file1文件,编译运行,可以看到返回值为3

删除file1,再运行代码对其进行打开操作,返回值为-1

  1. //打开当前目录下的file1文件
  2. //当打开文件失败时,创建该文件
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <stdio.h>
  7. int main()
  8. {
  9. int fd;
  10. fd=open("./file1",O_RDWR);
  11. if(fd==-1){
  12. printf("open file1 failed\n");
  13. fd=open("./file1",O_RDWR|O_CREAT,0600);//0600是文件的访问权限为文件所有者可读可写
  14. if(fd>0){
  15. printf("create file1 successed\n");
  16. }
  17. }
  18. return 0;
  19. }

文件的创建

  1. 需要包含的头文件:<sys/types.h>, <sys/stat.h>, <fcntl.h>

  1. 返回值:fd文件描述符

  1. 参数含义:

pathname:要创建的文件名(含路径,缺省位当前路径)

mode:创建模式

  1. S_IRUSR: 可读

  1. S_IWUSR: 可写

  1. S_IXUSR: 可执行

  1. S_IRWXU: 可读可写可执行

  1. 作用:从buf缓冲区中写入count个字节到文件中

  1. 相关应用:

  1. //在当前目录下创建一个可读可写可执行得到file2文件
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. int main()
  8. {
  9. int fd;
  10. char *buf="write file";
  11. fd =creat("./file2",S_IRWXU);
  12. return 0;
  13. }

文件写入操作

  1. 需要包含的头文件:<unistd.h>

  1. 返回值:写入成功,返回写入的字节个数,写入失败返回-1

  1. 参数含义:fd:文件描述符,buf:缓冲区 ,count:写入字节数

  1. 作用:从buf缓冲区中写入count个字节到文件中

  1. 相关应用:

  1. //将“write file”写入file1文件中
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. int main()
  8. {
  9. int fd;
  10. char *buf="write file";
  11. fd=open("./file1",O_RDWR);
  12. if(fd==-1){
  13. printf("open file1 failed\n");
  14. fd=open("./file1",O_RDWR|O_CREAT,0600);
  15. if(fd>0){
  16. printf("create file1 successed\n");
  17. }
  18. }
  19. printf("open success fd=%d\n",fd);
  20. write(fd,buf,strlen(buf));//此处不能使用sizeof,必须使用strlen,sizeof计算的是buf指针的大小,strlen计算的才是指针指向内容的字节大小
  21. close(fd);
  22. return 0;
  23. }

文件读取操作

  1. 需要包含的头文件:<unistd.h>

  1. 返回值:读取成功,读到多少字节就返回多少;读取失败返回0;读取错误返回-1

  1. 参数含义:fd:文件描述符,buf:缓冲区 ,count:读取字节数

  1. 作用:从文件中读取count个字节到buf缓冲区

  1. 相关应用:

  1. //读取file1文件中的内容
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <stdlib.h>
  9. int main()
  10. {
  11. int fd;
  12. char *buf="write file";
  13. fd=open("./file1",O_RDWR);
  14. if(fd==-1){
  15. printf("open file1 failed\n");
  16. fd=open("./file1",O_RDWR|O_CREAT,0600);
  17. if(fd>0){
  18. printf("create file1 successed\n");
  19. }
  20. }
  21. printf("open success fd=%d\n",fd);
  22. int cnt_write=write(fd,buf,strlen(buf));
  23. if(cnt_write !=-1){
  24. printf("write %d byte to file1\n",cnt_write);
  25. }
  26. close(fd);
  27. fd=open("./file1",O_RDWR);//此处关闭文件再重新打开的目的是让光标重新回到文件头,这样才能读取到写入的内容,也可以使用光标重定位lseek来进行此操作
  28. char *readBuf;
  29. readBuf=(char *)malloc(sizeof(char)*cnt_write+1);//这里必须对readBUf进行空间开辟,不然readBuf没有具体的指向,会发生段错误。
  30. int cnt_read=read(fd,readBuf,cnt_write);//读取的大小不一定必须是写入的大小,可以是任意值,但是读取到的内容,只有写入的内容那么大,比如读取的是100字节,但是读取完之后的内容依然只有10字节
  31. printf("read %d ,context:%s\n",cnt_read,readBuf);
  32. close(fd);
  33. return 0;
  34. }

文件光标移动操作

在进行读取时,我们使用了关闭文件再重新打开文件的方式,这种方式就有点垃圾了,我们可以使用lessk直接移动光标

  1. 需要包含的头文件:<sys/types.h>,<unistd.h>

  1. 返回值:调用成功,返回对于文件头的偏移值

  1. 参数含义:

fd:文件描述符

offset:当offset为负数,对于whence往前移,当offset为正数,对于whence往后移

whence:

  1. SEEK_SET:文件头

  1. SEEK_CUR:当前位置

  1. SEEK_END:文件尾

  1. 作用:将文件读写指针相对whence移动offset个字节

  1. 相关应用:

  1. //对于前面的读取文件内容的代码,进行修改
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <stdlib.h>
  9. int main()
  10. {
  11. int fd;
  12. char *buf="write file";
  13. fd=open("./file1",O_RDWR);
  14. if(fd==-1){
  15. printf("open file1 failed\n");
  16. fd=open("./file1",O_RDWR|O_CREAT,0600);
  17. if(fd>0){
  18. printf("create file1 successed\n");
  19. }
  20. }
  21. printf("open success fd=%d\n",fd);
  22. int cnt_write=write(fd,buf,strlen(buf));
  23. if(cnt_write !=-1){
  24. printf("write %d byte to file1\n",cnt_write);
  25. }
  26. // close(fd);
  27. // fd=open("./file1",O_RDWR);
  28. lseek(fd,-cnt_write,SEEK_END);//从文件尾像前移动写入的字节数,也相当于lssek(fd,0,SEEK_SET)
  29. char *readBuf;
  30. readBuf=(char *)malloc(sizeof(char)*cnt_write+1);
  31. int cnt_read=read(fd,readBuf,cnt_write);
  32. printf("read %d ,context:%s\n",cnt_read,readBuf);
  33. close(fd);
  34. return 0;
  35. }
  1. //巧用lseek对文件大小进行计算
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <stdlib.h>
  9. int main()
  10. {
  11. int fd;
  12. char *buf="write file";
  13. fd=open("./file1",O_RDWR);
  14. int fileSize=lseek(fd,0,SEEK_END);//利用lseek的返回值是对于文件头的偏移值,我们可以直接将光标移到文件尾,就可以巧妙的计算文件的字节大小了
  15. printf("file size is:%d\n",fileSize);
  16. close(fd);
  17. return 0;
  18. }

文件编程应用1——实现Linux cp命令

  1. //main函数的参数,来读取cp aa bb命令中的两个文件
  2. #include <stdio.h>
  3. int main(int argc, char **argv) //argc是参数的总个数,argv是数组指针,每个数组指针指向的内容是相应的参数
  4. {
  5. printf("total paeams:%d",argc);
  6. printf("No.1 params:%s\n",argv[0]);
  7. printf("No.2 params:%s\n",argv[1]);
  8. printf("No.3 params:%s\n",argv[2]);
  9. return 0;
  10. }
  1. //编写代码实现Linux cp命令
  2. /*实现思路:打开源文件src.c,读源文件src.c到缓冲区buf,打开/创建目标文件des.c,将缓冲区buf的内容写入到目标des.c,关闭两个文件*/
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. int main(int argc, char **argv)
  10. {
  11. int fd_src;
  12. int fd_des;
  13. char *readBuf=NULL;
  14. if(argc !=3){
  15. printf("param error\n");
  16. exit(-1);
  17. }
  18. fd_src=open(argv[1],O_RDWR);
  19. int size=lseek(fd_src,0,SEEK_END);
  20. lseek(fd_src,0,SEEK_SET);
  21. readBuf=(char *)malloc(sizeof(char)*size+8);
  22. int n_read=read(fd_src,readBuf,size);
  23. fd_des=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);
  24. int n_write=write(fd_des,readBuf,strlen(readBuf));
  25. close(fd_src);
  26. close(fd_des);
  27. return 0;
  28. }

文件编程应用2——修改程序的配置文件

在这之前需要先了解strstr()这个API

  1. 需要包含的头文件:<string.h>

  1. 返回值:需要找的特定字符串出现的首位置,返回的是一个字符型指针

  1. 参数含义:haystack:要操作的字符串 ,needle:找到的字符串

  1. 作用:从字符串中找出特定的字符串


现有配置文件如下,将LENG=3 修改为 LENG=5

  1. //修改LENG=3为LENG=5的步骤如下
  2. //1.找到LENG=3出现的首位置
  3. //2.该位置记录下来
  4. //3.再将位置向后移动到需要修改的地方,即移动到3的位置,再将5赋值给指针指向的位置
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. int main(int argc, char **argv)
  12. {
  13. int fd_src;
  14. char *readBuf=NULL;
  15. if(argc !=2){
  16. printf("param error\n");
  17. exit(-1);
  18. }
  19. fd_src=open(argv[1],O_RDWR);
  20. int size=lseek(fd_src,0,SEEK_END);
  21. lseek(fd_src,0,SEEK_SET);
  22. readBuf=(char *)malloc(sizeof(char)*size+8);
  23. int n_read=read(fd_src,readBuf,size);
  24. char *p=strstr(readBuf,"LENG=");
  25. if(p==NULL){
  26. printf("not found");
  27. exit(-1);
  28. }
  29. p=p+strlen("LENG+");
  30. *p='5';//一定要是字符'5',在文件中的内容都是字符型的
  31. lseek(fd_src,0,SEEK_SET);//光标重新定位,让缓冲区中修改后的内容重新覆盖掉源文件中的内容
  32. int n_write=write(fd_src,readBuf,strlen(readBuf));
  33. close(fd_src);
  34. return 0;
  35. }

编译运行之后,再打开需要修改的文件,就可以看到已经修改好了

写一个整数到文件

上面修改文件配置文件时,写入文件的是一个字符,并且文件中的内容都是字符型的,那么怎样才能将一个整型数写入到文件呢

可以从手册中看到,buf其实是一个无类型的指针,所以不仅仅是可以传递一个字符型指针,也可以是一个指向整型数的地址

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. int main(int argc, char **argv)
  8. {
  9. int fd;
  10. int x=100;
  11.         int y=0;
  12. fd=open("./file2",O_RDWR);
  13. int n_write=write(fd,&x,sizeof(int));//将x地址指向的值写入到file2里面
  14. lseek(fd,0,SEEK_SET);//光标重定位,将光标定位到文件头
  15. int n_read=read(fd,&y,sizeof(int));//从file2中将x读到y所指向的地址空间中
  16. printf("read:%d",y);       
  17. close(fd);
  18. return 0;
  19. }

写结构体数组到文件

  1. 写结构体到文件

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. struct test
  8. {
  9. int a;
  10. char b;
  11. };
  12. int main()
  13. {
  14. int fd;
  15. struct test x={100,'a'};
  16. struct test y;
  17. fd=open("./file2",O_RDWR);
  18. int n_write=write(fd,&x,sizeof(struct test));
  19. lseek(fd,0,SEEK_SET);
  20. int n_read=read(fd,&y,sizeof(struct test));
  21. printf("read:%d,%c\n",y.a,y.b);
  22. close(fd);
  23. return 0;
  24. }
  1. 写结构体数组到文件

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. struct test
  8. {
  9. int a;
  10. char b;
  11. };
  12. int main()
  13. {
  14. int fd;
  15. struct test x[2]={{100,'a'},{101,'b'}};
  16. struct test y[2];
  17. fd=open("./file2",O_RDWR);
  18. int n_write=write(fd,&x,sizeof(struct test)*2);
  19. lseek(fd,0,SEEK_SET);
  20. int n_read=read(fd,&y,sizeof(struct test)*2);
  21. printf("read:%d,%c\n",y[0].a,y[0].b);
  22. printf("read:%d,%c\n",y[1].a,y[1].b);
  23. close(fd);
  24. return 0;
  25. }

以此类推,也可以将链表等写入到文件中

标准C库打开创建文件读写光标移动

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main()
  4. {
  5. FILE *fp;
  6. char readBuf[1024]={0};
  7. char *str="write file";
  8. fp=fopen("./file1","w+");
  9. fwrite(str,sizeof(char),strlen(str),fp);
  10. fseek(fp,0,SEEK_SET);
  11. fread(readBuf,sizeof(char),strlen(str),fp);
  12. printf("read data: %s\n",readBuf);
  13.         fclose(fp);
  14. return 0;
  15. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/182954
推荐阅读
相关标签
  

闽ICP备14008679号