当前位置: 首页 > news >正文

【Linux系统编程】02:文件操作

文件IO


  • 系统调用(不带缓冲的IO操作)
  • 库函数(默认带用户缓冲的IO操作)

一、非缓冲IO

  • 系统调用:即为不带缓冲的IO

1.打开文件open

在这里插入图片描述

在这里插入图片描述

2.读取文件read

NAMEread - read from a file descriptorSYNOPSIS#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);DESCRIPTIONread() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.On  files that support seeking, the read operation commences at the file offset, and the file offset is incremented by 	        the number of bytes read.  If the file offset is at or past the end of file, no bytes are read, and read() returns zero.If count is zero, read() may detect the errors described below.  In the absence of any errors, or if read() does not            check for errors, a read() with a count of 0 returns zero and has no other effects.According to POSIX.1, if count is greater than SSIZE_MAX, the result is implementation-defined; see NOTES for the upper          limit on Linux.RETURN VALUEOn success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this        number.  It is not an error if this number is smaller  than  the  number  of  bytes requested;  this  may  happen  for          example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we          are reading from a pipe, or from a terminal), or because read() was interrupted by a signal.  See also NOTES.On error, -1 is returned, and errno is set appropriately.  In this case, it is left unspecified whether the file position        (if any) changes.
  • fd:文件描述符
  • buf:一块内存的首地址,用于存放读取的数据
  • count:读取的字节数
  • 返回值:读取到的字节数,0表示文件读取结束

3.写入文件write

在这里插入图片描述

4.关闭文件close

在这里插入图片描述

5.创建文件create

在这里插入图片描述

二、案例使用

1.文件读操作

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>int main(int argc, char *argv[]) {int fd;if (argc < 2) {fprintf(stderr, "Usage : %s file\n", argv[0]);exit(1);}if ((fd = open(argv[1], O_RDONLY)) == -1) {perror("open");fprintf(stderr, "%d\n", errno);exit(1);}while (1) {char buff[512] = {0};//buff用于存放读出内容ssize_t num;if ((num = read(fd, buff, sizeof(buff))) > 0) {//0表示读到文件末尾 -1表示出错printf("%s", buff);} else {break;}}close(fd);return 0;
}

在这里插入图片描述

由于文件较大char buff[512]字节无法一次性读完,两次buff读的中间出现会一些特殊的符号(数组的结束位置\0被覆盖)。

为了解决上述问题,可以通过临时将buff[]数组的最后一个元素赋值为\0将其结束,从而解决buff[]数组后一个位置被覆盖的问题(有可能越界赋值)。

在这里插入图片描述

2.文件拷贝操作

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>int main(int argc, char *argv[]) {int fd1, fd2;if (argc < 3) {fprintf(stderr, "Usage : %s file1 file2\n", argv[0]);exit(1);}if ((fd1 = open(argv[1], O_RDONLY)) == -1) {perror("open1");fprintf(stderr, "%d\n", errno);exit(1);}if ((fd2 = open(argv[2], O_RDWR | O_CREAT, 0660)) == -1) {perror("open2");fprintf(stderr, "%d\n", errno);exit(1);}//文件拷贝操作while (1) {char buff[512] = {0};//buff用于存放读出内容buff[512] = '\0';ssize_t num1;ssize_t num2;if ((num1 = read(fd1, buff, sizeof(buff))) > 0) {//0表示读到文件末尾 -1表示出错//将读出的文件buff写入目标文件, 如果写入失败则直接退出循环if ((num2 = write(fd2, buff, num1)) < 0) break;} else {break;}}close(fd1);close(fd2);return 0;
}

在这里插入图片描述

文件拷贝成功。

三、缓冲IO

  • 库函数:即为默认带用户缓冲的IO操作(标准IO/用户缓冲IO)

1.打开文件fopen

在这里插入图片描述

2.读取文件fread

在这里插入图片描述

3.写入文件fwrite

在这里插入图片描述

4.关闭文件fclose

在这里插入图片描述

四、案例使用

1.文件拷贝

#include "head.h"int main(int argc, char *argv[]) {int opt;char rname[50] = {50}, wname[50] = {0};FILE *r, *w;//文件打开while ((opt = getopt(argc, argv, "r:w:")) != -1) {switch (opt) {case 'r' :strcpy(rname, optarg);break;case 'w' :strcpy(wname, optarg);break;default:fprintf(stderr, "Usage : %s -r file1 -w file2\n", argv[0]);break;}}if (!strlen(rname) || !strlen(wname)) {//判定 -r -w的参数是否为空fprintf(stderr, "Usage : %s -r file1 -w file2\n", argv[0]);exit(1);}if ((r = fopen(rname, "r")) == NULL) {//判定以r形式的文件是否打开成功perror("fopen1");exit(1);}if ((w = fopen(wname, "w")) == NULL) {//判定以w形式的文件是否打开成功perror("fopen2");exit(1);}//文件读取 写入ssize_t num;while (1) {char buff[1024] = {0};if ((num = fread(buff, 1, sizeof(buff), r)) > 0) {fwrite(buff, 1, num, w);} else {break;}}fclose(r);fclose(w);return 0;
}

在这里插入图片描述

http://www.lryc.cn/news/4605.html

相关文章:

  • 华为OD机试 - 去除多余空格(Python)| 真题+思路+代码
  • 百趣代谢组学分享,补充α-酮酸的低蛋白饮食对肾脏具有保护作用
  • json对象和formData相互转换
  • 【c++面试问答】常量指针和指针常量的区别
  • Ubuntu18下编译android的ffmpeg经验
  • Spring Security in Action 第十三章 实现OAuth2的认证端
  • 本文章提供中国国界、国界十段线原始数据以及加载方法
  • 一文带你搞懂,Python语言运算符
  • JAVA集合专题4 —— Map
  • 二叉树进阶--二叉搜索树
  • 牛客网Python篇数据分析习题(三)
  • Java开发常见关键词集绵
  • 解决idea出现的java.lang.OutOfMemoryError: Java heap space的问题
  • 为什么子进程要继承处理器亲缘性?
  • 【算法】高精度
  • 计算机网络-基本概念
  • 你评论,我赠书~【哈士奇赠书 - 13期】-〖Python程序设计-编程基础、Web开发及数据分析〗参与评论,即可有机获得
  • 【设计模式】我终于读懂了代理模式。。。
  • 每天10个前端小知识 【Day 2】
  • 帮助中心在线制作工具推荐这4款,很不错哟!
  • rabbitMQ相关文章汇总
  • 【C++】异常
  • @Validated注解不生效问题汇总
  • 华科万维C++章节练习2_4
  • 17万字数字化医院信息化建设大数据平台建设方案WORD
  • Android 11系统签名修改
  • 亚马逊、沃尔玛卖家自养号退款经验和测评技术
  • Spring Security in Action 第十一章 SpringSecurity前后端分离实战
  • 高级前端二面vue面试题(持续更新中)
  • 七大设计原则之依赖倒置原则应用