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

Linux文件编程——write函数

在 Linux 文件编程中,write 函数是一个系统调用,用于将数据从缓冲区写入文件描述符(file descriptor)指向的文件或设备。它是 Unix/Linux 系统编程中非常重要的底层 I/O 操作之一。以下是 write 函数的详细使用方法和注意事项:


1. 函数原型

#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);
  • 参数
    • fd:文件描述符(File Descriptor),通过 open 或 creat 等函数获得。
    • buf:指向要写入数据的缓冲区的指针。
    • count:要写入的字节数。
  • 返回值
    • 成功时返回实际写入的字节数(可能小于 count)。
    • 失败时返回 -1,并设置 errno 表示错误原因。

2. 使用方法

基本示例
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>int main() {int fd;char buf[] = "Hello, Linux!";ssize_t bytes_written;// 打开文件(如果不存在则创建,权限为 rw-r--r--)fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);if (fd == -1) {perror("open failed");return 1;}// 写入数据bytes_written = write(fd, buf, strlen(buf));if (bytes_written == -1) {perror("write failed");close(fd);return 1;}printf("Successfully wrote %zd bytes\n", bytes_written);// 关闭文件close(fd);return 0;
}
关键步骤
  1. 打开文件
    • 使用 open 函数获取文件描述符,指定写入模式(如 O_WRONLYO_RDWR)和创建选项(如 O_CREAT)。
    • 设置文件权限(如 0644 表示 rw-r--r--)。
  2. 写入数据
    • 调用 write(fd, buf, count),将 buf 中的数据写入文件。
    • 检查返回值,确保写入成功。
  3. 关闭文件
    • 使用 close(fd) 释放文件描述符。

3. 注意事项

(1) 返回值处理
  • write 可能不会一次性写入所有请求的数据(尤其是写入大文件或慢速设备时)。
  • 必须检查返回值,并在必要时循环写入剩余数据:
ssize_t total_written = 0;
while (total_written < count) {ssize_t bytes_written = write(fd, buf + total_written, count - total_written);if (bytes_written == -1) {perror("write failed");break;}total_written += bytes_written;
}
(2) 错误处理
  • 常见错误包括:
    • EBADF:无效的文件描述符。
    • ENOSPC:磁盘空间不足。
    • EINTR:被信号中断(需重试)。
    • EIO:底层 I/O 错误。
  • 使用 perror 或 strerror(errno) 打印错误信息。
(3) 缓冲与非阻塞 I/O
  • write 是无缓冲的(直接调用系统调用),但文件可能因缓冲设置(如 O_DIRECT)或设备特性而延迟写入。
  • 对于非阻塞文件描述符(如套接字),write 可能返回 EAGAIN 或 EWOULDBLOCK,需结合 select/poll 使用。
(4) 性能优化
  • 批量写入(减少系统调用次数)。
  • 使用 O_DIRECT 绕过内核缓冲(需对齐内存和文件偏移)。
  • 对于大文件,考虑 pwrite 进行分散/聚集写入(Scatter-Gather I/O)。
(5) 安全性
  • 确保缓冲区 buf 的有效性,避免越界访问。
  • 验证文件描述符 fd 的合法性(如通过 fstat 检查)。
(6) 信号中断
  • 如果 write 被信号中断(EINTR),通常需要重新尝试写入。

4. 替代函数

  • pwrite:在指定偏移量处写入(无需 lseek)。
  • writev:分散写入(从多个缓冲区写入数据)。
  • sendfile:零拷贝文件传输(适用于网络或进程间通信)。

5. 总结

write 是 Linux 文件编程的基础函数,使用时需注意:

  1. 正确处理返回值和错误。
  2. 确保数据完整写入(循环写入)。
  3. 结合文件打开模式和权限设置。
  4. 考虑性能和安全性优化。

通过合理使用 write,可以高效、可靠地完成文件 I/O 操作。

http://www.xdnf.cn/news/5680.html

相关文章:

  • FastMCP v2:构建MCP服务器和客户端的Python利器
  • bootstrap table 添加跳转到指定页的功能(仅自己可见)
  • nestjs[一文学懂如何在nestjs中对npm功能包封装]
  • Spring AI系列——使用大模型对文本进行内容总结归纳分析
  • Android中ConstraintLayout布局定位使用详解
  • Cabot:开源免费的 PagerDuty 替代品,让系统监控更简单高效
  • K8S已经成为了Ai应用运行的平台工具
  • 架构思维:通用架构模式_系统监控的设计
  • OpenCV 的 CUDA 模块中用于将多个单通道的 GpuMat 图像合并成一个多通道的图像 函数cv::cuda::merge
  • Go语言多线程爬虫与代理IP反爬
  • 集成指南:如何采用融云 Flutter IMKit 实现双端丝滑社交体验
  • 交易流水表的分库分表设计
  • Home Assistant 米家集成:开启智能家居新体验
  • mac M2下的centos8:java和jenkins版本匹配,插件安装问题
  • # 07_Elastic Stack 从入门到实践(七)---1
  • linux小主机搭建自己的nas(三)docker安装nextcloud
  • AI日报 - 2024年05月13日
  • WinRAR技巧:巧用整理密码,简化加密流程
  • .NET 在鸿蒙系统上的适配现状
  • Python, FastAPI 与 RESTful API:构建高效 Web 服务的指南
  • Spring的异步
  • 《Python星球日记》 第58天:Transformer 与 BERT
  • find--命令基础
  • 企业级常用的 CentOS版本
  • 智能手表 MCU 任务调度图
  • 用postman的时候如何区分服务器还是自己的问题?
  • java基础-注解和反射
  • 9.0 C# 调用solidworks介绍1
  • 分词器工作流程和Ik分词器详解
  • SMT贴片加工技术解析与应用要点