c++怎么处理fstream超出2GB文件大小限制__fseeki64大文件指针【避坑】

轻枫小哥_8471

轻枫小哥_8471

2026-03-23

587人浏览

原创

windows下fstream读写>2gb文件失败,因msvc默认链接旧crt导致32位偏移截断;应改用_fseeki64/_ftelli64、createfile+setfilepointerex,或全程统一i/o范式。

c++怎么处理fstream超出2gb文件大小限制__fseeki64大文件指针【避坑】

fstream 在 Windows 上读写 >2GB 文件为什么会失败

默认编译下,std::fstream 底层调用的是 32 位偏移的 _lseek 或 fseek,即使你用 seekg/seekp 传入 std::streamoff(通常是 long long),Windows CRT 仍可能截断高 32 位——表现为文件指针跳转错乱、read() 返回 0、eof() 提前触发。

这不是 C++ 标准问题,是 MSVC 默认链接旧版 CRT 的行为;Linux/glibc 下通常无此限制(off_t 默认 64 位)。

必须启用 _FILE_OFFSET_BITS=64 和 /D"_CRT_SECURE_NO_WARNINGS"

仅加 /D"_USE_32BIT_TIME_T" 没用,关键在两处:

  • 编译时定义 _FILE_OFFSET_BITS=64(MSVC 不原生支持该宏,但需等效操作)
  • 链接时强制使用支持大文件的 CRT 版本:VS2015+ 默认已支持,但必须关闭“SDL 检查”并确保未手动链接 libcmt.lib 等旧库
  • 更稳妥的做法:用 std::ios_base::ate | std::ios_base::binary 打开,避免依赖 seekp(0, std::ios::end) 计算大小(该调用在旧 CRT 下极易出错)

用 _fseeki64 + _ftelli64 替代标准流定位(最稳方案)

绕过 fstream 的封装,直接操作底层 FILE* 句柄。虽然失去 RAII,但对超大文件控制更精确、行为可预测。

实操步骤:

Upload audio to AIOZ Stream
Upload audio to AIOZ Stream

快速上传音频至 AIOZ Stream API。支持默认或自定义编码配置创建音频对象,上传文件并完成处理后返回音频链接。

下载
  • 用 fopen 打开文件,模式加 "b"(如 "rb")
  • 用 _fseeki64(fp, offset, SEEK_SET) 定位,offset 类型为 __int64
  • 用 _ftelli64(fp) 获取当前位置,返回 __int64
  • 读写仍用 fread/fwrite,别混用 fstream::read

示例片段:

FILE* fp = fopen("huge.bin", "rb");
if (fp) {
    _fseeki64(fp, 3000000000LL, SEEK_SET); // 跳到 3GB 处
    char buf[4096];
    size_t n = fread(buf, 1, sizeof(buf), fp);
    __int64 pos = _ftelli64(fp); // 正确拿到 3GB+ 偏移
    fclose(fp);
}

用 CreateFile + SetFilePointerEx(Windows 原生 API)

当需要精确控制缓存、重叠 I/O 或处理稀疏文件时,C Runtime 层已不够用。Windows 原生 API 天然支持 64 位偏移。

注意点:

  • CreateFile 必须指定 FILE_FLAG_NO_BUFFERING(若需对齐读写)或至少 FILE_ATTRIBUTE_NORMAL
  • SetFilePointerEx 的 lpDistanceToMove 是 LARGE_INTEGER,直接支持 64 位
  • 不能和 stdio 函数混用同一文件句柄(会破坏内部缓冲区状态)
  • 记得用 CloseHandle,不是 fclose

关键调用示例:

HANDLE h = CreateFile(L"bigfile.dat", GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
if (h != INVALID_HANDLE_VALUE) {
    LARGE_INTEGER li;
    li.QuadPart = 5000000000LL; // 5GB
    SetFilePointerEx(h, li, &li, FILE_BEGIN);
    DWORD read;
    ReadFile(h, buf, sizeof(buf), &read, nullptr);
    CloseHandle(h);
}

真正容易被忽略的是:哪怕用了 _fseeki64,如果之前用 fstream 打开过这个文件,再用 fileno() 取句柄去调 _fseeki64,依然可能因缓冲区不同步导致位置错乱。最干净的做法是——从头到尾只用一种 I/O 范式,别交叉。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

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

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

下载

相关标签:

c++ stream

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

相关专题

更多
fclose函数的用法
fclose函数的用法

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

2023.11.30

822

9

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

299

31

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3019

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

2578

6

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

2023.08.01

1428

3

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2359

5

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.08

3210

4

windows自动更新
windows自动更新

Windows操作系统的自动更新功能可以确保系统及时获取最新的补丁和安全更新,以提高系统的稳定性和安全性。然而,有时候我们可能希望暂时或永久地关闭Windows的自动更新功能。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

1457

3

windows boot manager
windows boot manager

windows boot manager无法开机的解决方法:1、系统文件损坏,使用Windows安装光盘或USB启动盘进入恢复环境,选择修复计算机,然后选择自动修复;2、引导顺序错误,进入恢复环境,选择命令提示符,输入命令"bootrec /fixboot"和"bootrec /fixmbr",然后重新启动计算机;3、硬件问题,使用硬盘检测工具进行扫描和修复;4、重装操作系统。本专题还提供其他解决

2023.08.28

2377

4

热门下载

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

精品课程

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

共0课时 | 0人学习

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

共0课时 | 0人学习

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

共0课时 | 0人学习