news 2026/4/21 22:50:21

【C++与Linux基础】文件篇 -语言特性上的文件操作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C++与Linux基础】文件篇 -语言特性上的文件操作

【C++与Linux基础】文件篇 - 语言特性上的文件操作

在 C++ 中进行文件操作,主要依赖两种方式:

  1. C++ 标准库<fstream>)—— 现代 C++ 推荐方式,跨平台,面向对象风格
  2. C 风格文件操作<cstdio>中的fopenfread等)—— 仍然大量存在,尤其在与 C 代码混合、性能敏感或 Linux 系统编程场景中

此外,在 Linux 环境下,C++ 程序也经常直接使用系统调用<unistd.h>openreadwrite等)来实现更底层的文件/IO 操作。

下面按使用频率和推荐度逐一对比说明。

1. C++ 标准库方式(推荐现代写法)

#include<fstream>#include<iostream>#include<string>#include<vector>intmain(){// ------------------------------// 1. 写文件(推荐方式)// ------------------------------std::ofstreamofs("output.txt",std::ios::out|std::ios::trunc);if(!ofs.is_open()){std::cerr<<"无法打开文件\n";return1;}ofs<<"Hello, C++ file!\n";ofs<<"当前行: "<<__LINE__<<"\n";ofs<<3.14159<<" "<<42<<"\n";// 也可以用格式化(C++20 之后更方便)// ofs << std::format("pi = {:.4f}\n", 3.1415926535);ofs.close();// 通常可以省略,析构时自动关闭// ------------------------------// 2. 读文件 - 按行读取(最常用)// ------------------------------std::ifstreamifs("output.txt");if(!ifs.is_open()){std::cerr<<"无法打开文件\n";return1;}std::string line;while(std::getline(ifs,line)){std::cout<<line<<'\n';}// ------------------------------// 3. 一次性读入全部内容(适合小文件)// ------------------------------std::ifstreamin("config.ini",std::ios::in|std::ios::binary);if(in){std::stringcontent((std::istreambuf_iterator<char>(in)),std::istreambuf_iterator<char>());std::cout<<"文件全部内容长度: "<<content.size()<<'\n';}// ------------------------------// 4. 读写二进制文件// ------------------------------structRecord{intid;doublevalue;charname[32];};// 写std::ofstreambin_out("data.bin",std::ios::binary);Record r{1001,3.14159,"SensorA"};bin_out.write(reinterpret_cast<constchar*>(&r),sizeof(r));// 读std::ifstreambin_in("data.bin",std::ios::binary);Record r2;if(bin_in.read(reinterpret_cast<char*>(&r2),sizeof(r2))){std::cout<<r2.id<<" "<<r2.value<<" "<<r2.name<<'\n';}return0;}

C++ 文件流常用状态与标志

打开模式说明常用组合
std::ios::in以读方式打开读文件
std::ios::out以写方式打开(默认清空)写文件
std::ios::app追加模式日志文件
std::ios::trunc如果文件存在则清空(out 默认)重写文件
std::ios::binary二进制模式(不转换换行符)读写图片、struct、protobuf 等
std::ios::ate打开后立即定位到文件末尾追加写

2. C 风格文件操作(仍然非常常见)

#include<cstdio>#include<cstring>intmain(){// 写文件FILE*fp=fopen("log.txt","w");if(!fp){perror("fopen");return1;}fprintf(fp,"Time: %ld Error: %s\n",time(nullptr),"disk full");fputs("critical alert\n",fp);fclose(fp);// 读文件(按块读)charbuf[4096];FILE*in=fopen("large.bin","rb");if(in){size_t n;while((n=fread(buf,1,sizeof(buf),in))>0){// 处理 buf[0..n-1]}fclose(in);}// 定位 + 追加写FILE*log=fopen("server.log","a+");fseek(log,0,SEEK_END);// 可省略,因为 a 模式默认追加fprintf(log,"[INFO] connection from %s\n","192.168.1.100");return0;}

3. Linux 系统调用方式(底层、最灵活)

#include<unistd.h>#include<fcntl.h>#include<sys/stat.h>#include<sys/types.h>#include<cstring>#include<iostream>intmain(){// 打开文件intfd=open("raw.dat",O_RDWR|O_CREAT,0644);if(fd==-1){perror("open");return1;}// 写constchar*msg="Hello from syscall\n";write(fd,msg,strlen(msg));// 定位off_t pos=lseek(fd,0,SEEK_SET);if(pos==-1)perror("lseek");// 读charbuf[128];ssize_t n=read(fd,buf,sizeof(buf)-1);if(n>0){buf[n]='\0';std::cout<<"Read: "<<buf;}close(fd);// 追加写示例intlogfd=open("/var/log/app.log",O_WRONLY|O_APPEND|O_CREAT,0644);if(logfd!=-1){constchar*line="ERROR: connection timeout\n";write(logfd,line,strlen(line));close(logfd);}return0;}

4. 三种方式对比总结(2025–2026 视角)

方式跨平台易用性性能推荐场景现代 C++ 推荐度
std::fstream★★★★★中等日常开发、配置、日志、中等大小文件★★★★★
C 风格FILE*★★★★与 C 库交互、性能敏感、嵌入式、老代码★★★
Linux 系统调用★★最高高性能服务器、驱动开发、大文件处理、零拷贝★★(特定场景)

5. 现代 C++ 写文件操作的推荐实践(2024+)

  1. 优先使用std::ofstream/std::ifstream
  2. 小文件直接读入std::string(如上文方式)
  3. 大文件建议分块读取(避免一次性读入全部内容)
  4. 总是检查打开是否成功
  5. RAII 原则:尽量依赖析构自动关闭(不显式close()
  6. 日志类场景→ 考虑std::ofstream+std::ios::app
  7. 二进制数据→ 务必加上std::ios::binary
  8. 异常安全→ 可开启ifs.exceptions(std::ios::failbit | std::ios::badbit);

6. 常见问题快速定位

  • 文件打不开→ 检查路径、权限、是否被其他进程占用
  • Windows 和 Linux 换行符不同→ 文本模式下自动处理,二进制模式需注意
  • 写不进去→ 忘记flush()close(),或磁盘满
  • 读到乱码→ 忘记std::ios::binary或编码问题

下一节可以深入讲:

  • RAII 封装的文件类
  • mmap 内存映射文件
  • 异步文件 IO(io_uring)
  • 大文件分块读写 + 进度显示

你更想往哪个方向继续?或者有具体场景(日志、配置、二进制、超大文件等)想看最优实现?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 5:13:06

基于PLC的智能交通灯监控系统设计

基于PLC的智能交通灯监控系统设计 第一章 设计背景与核心目标 城市道路交通流量的动态变化&#xff0c;使得传统固定配时的交通灯系统存在通行效率低、路口拥堵、资源浪费等问题&#xff0c;难以适配早晚高峰、平峰期的差异化车流需求。PLC&#xff08;可编程逻辑控制器&#x…

作者头像 李华
网站建设 2026/4/18 5:12:47

AI云电脑是什么?一文读懂AI云电脑和普通电脑的区别

在数字化浪潮下&#xff0c;电脑早已成为工作与生活的必备工具。但你是否注意到&#xff0c;一种无需厚重主机的 “AI云电脑” 正悄然兴起&#xff1f;不少人对AI云电脑与普通电脑的区别一知半解&#xff0c;今天就为大家详细拆解两者的核心差异&#xff0c;同时揭秘兼具实用性…

作者头像 李华
网站建设 2026/4/18 5:13:10

更有可能胜出的 python 层结合 pytorch写 cuda kernel的技术方案

在未来&#xff0c;结合 pytorch&#xff0c;更有可能胜出的、成为主流的 python 层写 cuda kernel的技术方案&#xff08;cutile&#xff0c;tilelang&#xff0c;triton&#xff0c;..... &#xff09;这是一个非常关键的战略性问题。让我从技术趋势、生态博弈和实际部署角度…

作者头像 李华