讲师中心 微信公众号
AI工具推荐 视频效率加速

c++怎么在不加载全量数据的前提下高效获取超大文件的最后一行【进阶】

阿静小哥_8442

阿静小哥_8442

发布时间:2026-03-24 19:05:32

|

311人浏览过

|

来源于php中文网

原创

核心思路是用fseek从文件末尾倒查第一个'\n'以定位最后一行起始,需处理空文件、单行无换行、连续空行等边界,并避免频繁系统调用——推荐先fread末尾64KB到内存扫描,Fallback逐字节fseek。

c++怎么在不加载全量数据的前提下高效获取超大文件的最后一行【进阶】

用 fseek 从文件末尾反向扫描换行符

核心思路不是读完整个文件,而是从末尾往前找第一个 '\n',跳过末尾可能存在的空行或 EOF 符号。这要求文件是文本格式、换行符为 '\n'(Unix/Linux)或 "\r\n"(Windows),且不包含嵌入式 null 字节。

常见错误现象:fseek(fp, -1, SEEK_END) 后直接 fgetc,结果在空文件、单行文件、末尾无换行的文件里崩掉或返回错误字符。

  • 先 fseek(fp, 0, SEEK_END) 获取文件大小,若为 0 直接返回空
  • 用 ftell 记下当前位置,从 size - 1 开始倒序试探,但每次 fseek(..., -1, SEEK_CUR) 前要检查是否已到开头(pos == 0)
  • 遇到 '\n' 后再 fseek 一次到该位置之后(即下一行起始),然后用 fgets 读——但注意:如果最后一行没换行,就得读到 EOF
  • Windows 下若文件以 "\r\n" 结尾,只识别 '\n' 就够了;但若手动处理 '\r',容易把 "\r\n" 当成两行

处理边界情况:空文件、单行、末尾无换行

这些不是“异常”,而是真实存在的情况。比如日志轮转刚生成的文件、echo -n "hello" > big.log 这种场景,不覆盖就出错。

典型错误:循环中未判断 fseek 是否失败(如返回 -1),或未区分 pos == 0 时是“找到开头”还是“越界”。

立即学习“C++免费学习笔记(深入)”;

C++ 算法竞赛自动化测试数据生成与校验框架
C++ 算法竞赛自动化测试数据生成与校验框架

根据原题生成新题面、验证器及完整测试数据,自动套用 testlib 模板,用于用户要求生成测试数据时。

下载
  • 空文件:stat 或 fseek+ftell 得到 size == 0,直接返回空字符串
  • 单行无结尾换行:扫描到 pos == 0 仍未见 '\n',此时从头 fseek(fp, 0, SEEK_SET),再 fgets
  • 末尾多个换行(如 \n\n):需跳过所有连续的 '\n' 和 '\r',直到碰到非空白或到达开头

性能关键:避免频繁 fseek + fgetc 系统调用

每调用一次 fseek + fgetc,底层至少触发一次 lseek + read(1),对超大文件(10GB+)哪怕只扫几百字节,系统调用开销也会明显拉高延迟。

更优做法是用 mmap(Linux/macOS)或 CreateFileMapping(Windows)把末尾一段(如 8KB)映射进内存,然后在内存里倒查 '\n'。但这需要处理页面对齐、文件长度不足映射大小等细节。

  • 保守方案:一次性 fread 最后 64KB 到缓冲区,再在内存里从末尾向前找 '\n'
  • 注意缓冲区起始位置要对齐到可能的行首——读取范围建议为 min(file_size, 65536),从 buf + len - 1 开始扫
  • 若最后一行超长(>64KB),该法失效,得回退到逐字节 fseek,但概率极低,可加 fallback 提示

C++ 流对象(std::ifstream)不适合这个任务

std::ifstream 的 seekg 在文本模式下行为不可靠:Windows 上会把 "\r\n" 当作一个字符处理,导致偏移计算错误;且不保证 seekg 后的 get() 与 C stdio 的 fseek/fgetc 语义一致。

实测中,用 seekg(-1, std::ios::end) 在跨平台代码里极易读错位置,尤其当文件由不同系统生成时。

  • 坚持用 C FILE*(FILE*)配合 fseek/fgetc/fgets,控制确定
  • 若必须用 C++ RAII,可用 std::unique_ptr<FILE, int(*)(FILE*)> 包裹 fopen,析构时调 fclose
  • 别碰 std::fstream::seekp 或 seekg 文本模式——这不是设计用来干这事的

最麻烦的其实是换行符歧义和 mmap 页面边界对齐,这两处一不留神就会在某台机器上读出半截乱码。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

529

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1658

2024.03.01

fclose函数的用法
fclose函数的用法

fclose是一个C语言和C++中的标准库函数,用于关闭一个已经打开的文件,是文件操作中非常重要的一个函数,用于将文件流与底层文件系统分离,释放相关的资源。更多关于fclose函数的相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

822

2023.11.30

fgets在c语言中的用法
fgets在c语言中的用法

本专题整合了c语言中fgets用法介绍,阅读专题下面的文章了解更多详细内容。

133

2025.08.27

fgets在c语言中的用法
fgets在c语言中的用法

本专题整合了c语言中fgets用法介绍,阅读专题下面的文章了解更多详细内容。

133

2025.08.27

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1598

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2384

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

5884

2023.10.24

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

40

2026.09.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn