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

Linux文件IO(二)-文件操作使用详解

前篇已经讲过open打开文件的操作使用,本篇文章介绍剩余的wirte、read、close、lseek等操作。

1.write写文件

调用 write 函数可向打开的文件写入数据,其函数原型如下所示(可通过"man 2 write"查看):

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

首先使用 write 函数需要先包含 unistd.h 头文件。

函数参数和返回值含义如下:

**fd:**文件描述符。关于文件描述符,前面已经给大家进行了简单地讲解,这里不再重述!我们需要将进行写操作的文件所对应的文件描述符传递给 write 函数。

**buf:**指定写入数据对应的缓冲区。

**count:**指定写入的字节数。

**返回值:**如果成功将返回写入的字节数(0 表示未写入任何字节),如果此数字小于 count 参数,这不是错误,譬如磁盘空间已满,可能会发生这种情况;如果写入出错,则返回-1。

对于普通文件(我们一般操作的大部分文件都是普通文件,譬如常见的文本文件、二进制文件等),不管是读操作还是写操作,一个很重要的问题是:从文件的哪个位置开始进行读写操作?也就是 IO 操作所对应的位置偏移量,读写操作都是从文件的当前位置偏移量处开始,当然当前位置偏移量可以通过 lseek 系统调用进行设置,关于此函数后面再讲;默认情况下当前位置偏移量一般是 0,也就是指向了文件起始位置,当调用 read、write 函数读写操作完成之后,当前位置偏移量也会向后移动对应字节数,譬如当前位置偏移量为 1000 个字节处,调用 write()写入或 read()读取 500 个字节之后,当前位置偏移量将会移动到 1500 个字当调用 read、write 函数读写操作完成之后,当前位置偏移量也会向后移动对应字节数,譬如当前位置偏移量为 1000 个字节处,调用 write()写入或 read()读取 500 个字节之后,当前位置偏移量将会移动到 1500 个字节处。

2.read读文件

调用 read 函数可从打开的文件中读取数据,其函数原型如下所示(可通过"man 2 read"查看):

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

首先使用 read 函数需要先包含 unistd.h 头文件。

函数参数和返回值含义如下:

**fd:**文件描述符。与 write 函数的 fd 参数意义相同。

**buf:**指定用于存储读取数据的缓冲区。**count:**指定需要读取的字节数。

**返回值:**如果读取成功将返回读取到的字节数,实际读取到的字节数可能会小于 count 参数指定的字节数,也有可能会为 0,譬如进行读操作时,当前文件位置偏移量已经到了文件末尾。实际读取到的字节数少于要求读取的字节数,譬如在到达文件末尾之前有 30 个字节数据,而要求读取 100 个字节,则 read 读取成功只能返回 30;而下一次再调用 read 读,它将返回 0(文件末尾)

3. close关闭文件

可调用 close 函数关闭一个已经打开的文件,其函数原型如下所示(可通过"man 2 close"查看):

#include <unistd.h>

int close(int fd);

首先使用 close 函数需要先包含 unistd.h 头文件,当我们对文件进行 IO 操作完成之后,后续不再对文件进行操作时,需要将文件关闭。

函数参数和返回值含义如下:

**fd:**文件描述符,需要关闭的文件所对应的文件描述符。

**返回值:**如果成功返回 0,如果失败则返回-1。

除了使用 close 函数显式关闭文件之外,在 Linux 系统中,当一个进程终止时,内核会自动关闭它打开的所有文件,也就是说在我们的程序中打开了文件,如果程序终止退出时没有关闭打开的文件,那么内核会自动将程序中打开的文件关闭。很多程序都利用了这一功能而不显式地用 close 关闭打开的文件。

显式关闭不再需要的文件描述符往往是良好的编程习惯,会使代码在后续修改时更具有可读性,也更可靠,进而言之,文件描述符是有限资源,当不再需要时必须将其释放、归还于系统。

4. lseek读写指针位置

 

对于每个打开的文件,系统都会记录它的读写位置偏移量,我们也把这个读写位置偏移量称为读写偏移量,记录了文件当前的读写位置,当调用 read()或 write()函数对文件进行读写操作时,就会从当前读写位置偏移量开始进行数据读写。

读写偏移量用于指示 read()或 write()函数操作时文件的起始位置,会以相对于文件头部的位置偏移量来表示,文件第一个字节数据的位置偏移量为 0。

当打开文件时,会将读写偏移量设置为指向文件开始位置处,以后每次调用 read()、write()将自动对其进行调整,以指向已读或已写数据后的下一字节,因此,连续的调用 read()和 write()函数将使得读写按顺序递增,对文件进行操作。我们先来看看 lseek 函数的原型,如下所示(可通过"man 2 lseek"查看):

#include <sys/types.h>
#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);

首先调用 lseek 函数需要包含<sys/types.h>和<unistd.h>两个头文件。

函数参数和返回值含义如下:

**fd:**文件描述符。

**offset:**偏移量,以字节为单位。

**whence:**用于定义参数 offset 偏移量对应的参考值,该参数为下列其中一种(宏定义):

  • SEEK_SET:读写偏移量将指向 offset 字节位置处(从文件头部开始算);
  • SEEK_CUR:读写偏移量将指向当前位置偏移量 + offset 字节位置处,offset 可以为正、也可以为负,如果是正数表示往后偏移,如果是负数则表示往前偏移;
  • SEEK_END:读写偏移量将指向文件末尾 + offset 字节位置处,同样 offset 可以为正、也可以为负,如果是正数表示往后偏移、如果是负数则表示往前偏移。

**返回值:**成功将返回从文件头部开始算起的位置偏移量(字节为单位),也就是当前的读写位置;发生错误将返回-1。

使用示例:

  • 将读写位置移动到文件开头处:
off_t off = lseek(fd, 0, SEEK_SET);
if (-1 == off)
	return -1;
  • 将读写位置移动到文件末尾:
off_t off = lseek(fd, 0, SEEK_END);

if (-1 == off)
	return -1;
  • 将读写位置移动到偏移文件开头 100 个字节处:
off_t off = lseek(fd, 100, SEEK_SET);

if (-1 == off)
	return -1;
  • 获取当前读写位置偏移量:
off_t off = lseek(fd, 0, SEEK_CUR);
if (-1 == off)
		return -1;

函数执行成功将返回文件当前读写位置


http://www.kler.cn/news/312157.html

相关文章:

  • 论文解读《COMMA: Co-articulated Multi-Modal Learning》
  • mysql 重置密码
  • 部署Prometheus+Grafana批量监控Linux服务器
  • Django框架全面指南
  • 如何解决“json schema validation error ”错误? -- HarmonyOS自学6
  • 鸿蒙环境服务端签名直传文件到OSS
  • HTTP协议详解以及常见的状态码
  • 设计模式之外观设计模式
  • Ubuntu24.04部署docker
  • VD2811A SOP-8封装 可直接替代XB8886G芯片 大电流充放电锂保芯片
  • 智能机巢+无人机:自动化巡检技术详解
  • qt char*与QString互转
  • 巧用联合与枚举:解锁自定义类型的无限潜力
  • 【深度学习|PyTorch】基于 PyTorch 搭建 U-Net 深度学习语义分割模型——附代码及其解释!
  • 【HTTP】方法(method)以及 GET 和 POST 的区别
  • 控制浏览器显示隐藏c++
  • MySQL 主从复制部署与优化
  • 部署k8s基础环境
  • Java Web实战:利用三层架构与Servlet构建登录注册模块
  • 828华为云征文 | 云服务器Flexus X实例:部署 AgentOps,全方位监测智能体
  • Find My资讯|AirPods 4标准版充电盒无扬声器,Find My查找不会发出声音
  • Vue3:编写一个插件(进阶)
  • neuroph建立简单BP网络
  • windows消息机制
  • Spring Boot 项目中整合 RabbitMQ,使用死信队列(Dead Letter Exchange, DLX)实现延迟队列功能
  • 设计模式 组合模式(Composite Pattern)
  • 【HTTP】认识 URL 和 URL encode
  • KL散度(Kullback-Leibler)
  • java框架
  • 深入理解 MySQL MVCC:多版本并发控制的核心机制