You need to enable JavaScript to run this app. 如何重写fopen/ofstream等全局文件操作函数实现文件打开信息监控
优惠活动
大模型
产品
解决方案
定价
更多

如何重写fopen/ofstream等全局文件操作函数实现文件打开信息监控

实现无侵入监控文件打开的可行方案

注意事项

你示例中写的自定义fopen存在无限递归调用问题:自定义函数内直接调用fopen会再次触发你自己的实现,导致栈溢出,以下方案均已规避该问题。


方案1:宏替换(全平台通用,修改成本极低)

只要在项目全局引入的公共头文件(如预编译头)中加入以下定义即可,无需修改任何现有fopen调用代码:

#include <stdio.h>

// 自定义fopen包装实现
static FILE* wrapped_fopen(const char* filename, const char* mode) {
    printf("%s-%s\n", filename, mode);
    // 加括号避免宏展开,直接调用原生fopen
    return (fopen)(filename, mode);
}

// 预编译阶段将所有fopen调用替换为自定义实现
#define fopen(filename, mode) wrapped_fopen(filename, mode)
  • 优点:跨平台兼容,逻辑简单可控,可覆盖项目内所有显式fopen调用
  • 注意:如果有代码取fopen的函数指针,需写成&(fopen)才能获取原生函数地址

方案2:动态链接Hook(Linux平台,零代码修改)

如果连项目代码都不想改动,可以通过LD_PRELOAD运行时注入自定义实现,甚至可以监控第三方依赖库的fopen调用:

  1. 编写Hook代码hook_fopen.c:
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>

static FILE* (*original_fopen)(const char*, const char*) = NULL;

FILE* fopen(const char* filename, const char* mode) {
    // 首次调用时动态获取原生fopen地址
    if (!original_fopen) {
        original_fopen = dlsym(RTLD_NEXT, "fopen");
    }
    printf("%s-%s\n", filename, mode);
    return original_fopen(filename, mode);
}
  1. 编译为动态库:
    gcc -shared -fPIC hook_fopen.c -o libhookfopen.so -ldl
  2. 运行程序时注入即可:
    LD_PRELOAD=./libhookfopen.so ./你的可执行程序

Windows平台可以通过IAT Hook实现相同效果,原理为修改进程导入表中fopen的函数地址指向自定义实现。


方案3:C++ std::ofstream 等流类的监控

和fopen类似,用宏替换即可无侵入实现监控:

#include <fstream>
#include <cstdio>

class MonitoredOfstream : public std::ofstream {
public:
    MonitoredOfstream(const char* filename, std::ios_base::openmode mode = std::ios::out)
        : std::ofstream(filename, mode) {
        // 可自行将openmode转换为字符串输出
        printf("%s-%u\n", filename, (unsigned int)mode);
    }
};

#define ofstream MonitoredOfstream

所有现有ofstream对象创建代码无需修改,会自动触发自定义的监控逻辑。


内容的提问来源于stack exchange,提问作者Karthik K M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 13:36:02