c++如何在C和C++文件流之间转换_fileno获取文件描述符【附源码】

陌枫酱_2535

陌枫酱_2535

2026-03-22

749人浏览

原创

c++oding="utf-8" ?>

不行,_fileno不是标准c++函数,仅msvc/mingw等部分环境支持,且需流已打开、绑定真实文件、使用binary模式,并先获取file(但c++标准不暴露file),跨平台不可靠。

c++如何在c和c++文件流之间转换_fileno获取文件描述符【附源码】

用 _fileno 从 C++ std::fstream 拿到 C 文件描述符,行不行?

行,但必须确保流底层绑定的是真实文件(非内存、管道、重定向等),且已打开、未缓冲失败。_fileno 是 MSVC 和部分 POSIX 兼容环境(如 MinGW)提供的扩展函数,不是标准 C++,GCC/Clang 在纯 Linux 下默认不提供,会报 undefined reference to `_fileno'。

常见错误现象:std::ofstream f("out.txt"); int fd = _fileno(f); // fd == -1 或崩溃 —— 因为 f 内部 FILE* 可能未初始化或已被关闭。

  • 只对 std::fstream / std::ifstream / std::ofstream 有效,且必须用 std::ios_base::binary 模式打开(文本模式下换行处理可能干扰底层 fd 一致性)
  • 调用前务必检查流状态:if (f.is_open() && f.rdbuf() != nullptr)
  • MSVC 中需包含 <io.h></io.h>;MinGW 需链接 -lmsvcrt 或启用 -D__USE_MINGW_ANSI_STDIO

C++ 流怎么拿到对应的 FILE*?这是 _fileno 的前提

_fileno 输入是 FILE*,不是 C++ 流对象。C++ 标准库不暴露 FILE*,但各实现有私有接口:MSVC 提供 _get_stream_handle()(仅 debug 版可用),libc++ 和 libstdc++ 均不公开该能力。所以「先取 FILE* 再调 _fileno」这条路在跨平台项目里基本走不通。

实际能稳定用的路径只有一条:绕过 C++ 流,用 C 打开文件,再用 fdopen 构造 C++ 流 —— 反向操作更可靠。

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载
  • 正确姿势:int fd = open("data.bin", O_RDWR | O_CREAT, 0644); std::filebuf fb; fb.attach(fd); std::iostream fs(&fb);
  • 不要试图从 std::cout、std::cin 或重定向后的流取 fd —— 它们的 FILE* 可能被封装、复用或根本不存在(如 libc++ 用自研 buffer)
  • std::filebuf::fd() 是 GNU libstdc++ 的扩展(非标准),返回 int,但仅当用 attach() 绑定过 fd 后才有效;直接构造的流返回 -1

Linux/macOS 下替代 _fileno 的可移植方案

别硬啃 _fileno。POSIX 系统上,所有 I/O 最终都落到 fd,关键是怎么让 C++ 流和 fd 对齐。标准做法是:用 open() / socket() 等系统调用拿到 fd,再用 fdopen() 包装成 FILE*,最后用 std::filebuf 的非标准构造函数(libstdc++ 支持)或自己继承 std::streambuf 转接。

示例(libstdc++ 环境):

int fd = open("log.txt", O_WRONLY | O_APPEND | O_CREAT, 0644);
FILE* fp = fdopen(fd, "a");
std::filebuf fb;
fb.pubsetbuf(nullptr, 0);
fb.open("/dev/null", std::ios_base::out); // 占位
// 实际需反射调用 _M_file设为fp(不推荐)→ 更稳妥:直接用 fp + fprintf
  • 真正跨平台的做法是:放弃混合使用,同一模块统一用 C 文件 I/O(fread/fwrite)或统一用 C++ 流(read/write),中间不转换
  • 若必须桥接(如调第三方 C 库需要 fd),优先用 dup(fd) 复制一份,避免 C++ 流析构时误关原始 fd
  • 注意缓冲区同步:fflush(fp) 和 fs.flush() 不互通,混用极易丢数据

为什么你看到的「附源码」示例总在 Windows 上跑通?

因为 MSVC 的 std::filebuf 内部确实持有一个 FILE*,且 _fileno 就是直接读那个字段 —— 这属于实现细节泄漏。换个编译器、升个 libc++ 版本、甚至加个 -O2,就可能因内联优化导致 rdbuf() 返回空指针。

  • 测试时别只看是否编译通过,要验证 fd 是否真能 read()/write() —— 很多“成功”只是返回了某个无效值(如 3,其实是 stderr 的 fd)
  • CI 环境(尤其是 Linux + Clang)大概率挂掉,别信本地 Windows 测试结果
  • 最隐蔽的坑:std::ofstream f("x.txt", std::ios::app); int fd = _fileno(f.rdbuf()->_IO_file_flags ? ...) —— 这种野指针访问在 ASan 下立刻崩溃

真要拿 fd,就老实用 open();真要用 C++ 流,就别动它的底层。两者硬凑,边界模糊的地方比代码还多。

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

相关文章

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

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

下载

相关标签:

c++

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

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

5699

3

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.08.29

2845

6

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.29

3568

10

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.29

2525

10

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

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

2026.04.23

319

31

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3088

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

4549

12

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.12.29

3709

9

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

2026.01.19

406

15

热门下载

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

精品课程

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

共0课时 | 0人学习

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

共0课时 | 0人学习

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

共0课时 | 0人学习