You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows系统文件IO读写事件实时监控方案咨询

解决方案:Windows文件读写事件监控(Java环境)

方案一:PowerShell+ETW 轻量实现(无需编写原生代码)

Windows ETW(Event Tracing for Windows)是系统内置的事件追踪机制,可捕获文件IO读写事件,无需驱动。我们可以用PowerShell启动ETW会话,输出结构化日志,再通过Java解析其标准输出实现实时监控。

步骤1:PowerShell脚本实现ETW捕获

编写脚本FileIOMonitor.ps1,仅捕获读写事件并输出关键字段:

# 创建ETW会话,仅捕获FileIO的Read/Write事件
$sessionName = "FileIORawMonitor"
$providerName = "Microsoft-Windows-FileIO"

# 停止已有同名会话
wevtutil sl $sessionName /e:false 2>&1 | Out-Null
wevtutil cl $sessionName 2>&1 | Out-Null

# 启动会话,输出JSON格式的事件(包含文件名、字节数、偏移量)
wevtutil sl $sessionName /e:true /q:"*[System[Provider[@Name='$providerName'] and (EventID=3 or EventID=4)]]" /f:json
  • 事件ID3对应读操作,ID4对应写操作
  • 输出的JSON中,UserData.FileIoRead/UserData.FileIoWrite包含核心字段:
    • FileName:完整文件路径
    • IrpInfo.ByteOffset:文件内读写起始位置
    • IrpInfo.Length:读写字节数

步骤2:Java解析PowerShell输出

在Java中启动PowerShell进程,读取其标准输出并实时解析JSON:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class FileIOMonitor {
    public static void main(String[] args) throws Exception {
        // 启动PowerShell进程执行监控脚本
        Process process = new ProcessBuilder("powershell.exe", "-ExecutionPolicy", "Bypass", "-File", "FileIOMonitor.ps1")
                .redirectErrorStream(true)
                .start();

        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        ObjectMapper mapper = new ObjectMapper();
        String line;

        // 实时读取并解析输出
        while ((line = reader.readLine()) != null) {
            try {
                JsonNode event = mapper.readTree(line);
                JsonNode userData = event.get("UserData");
                if (userData == null) continue;

                String eventType = userData.fieldNames().next();
                JsonNode ioData = userData.get(eventType);
                String fileName = ioData.get("FileName").asText();
                long offset = ioData.get("IrpInfo").get("ByteOffset").asLong();
                long bytes = ioData.get("IrpInfo").get("Length").asLong();

                // 输出或处理监控数据
                System.out.printf("%s | 文件: %s | 偏移量: %d | 字节数: %d%n",
                        eventType.equals("FileIoRead") ? "读操作" : "写操作",
                        fileName, offset, bytes);
            } catch (Exception e) {
                // 忽略非JSON格式的系统提示行
                continue;
            }
        }
    }
}
  • 依赖Jackson库解析JSON,可通过Maven引入:com.fasterxml.jackson.core:jackson-databind:2.15.2
  • 需通过-ExecutionPolicy Bypass确保PowerShell允许运行脚本

方案二:JNI调用Windows ETW API(原生集成)

如果不想依赖PowerShell,可通过JNI直接调用Windows ETW用户态API,注册事件回调获取实时数据,全程无需编写内核驱动。

核心思路

  1. 编写C++代码,注册Microsoft-Windows-FileIO提供者,过滤Read/Write事件;
  2. 在C++回调中提取文件名、偏移量、字节数,传递给Java;
  3. Java通过JNI加载原生库,接收实时事件。

简化的C++代码片段(JNI部分)

#include <windows.h>
#include <evntrace.h>
#include <jni.h>
#include "FileIOMonitorJNI.h"

JavaVM* g_jvm;

// 事件回调函数
VOID WINAPI EventCallback(PEVENT_RECORD pEventRecord) {
    if (pEventRecord->EventHeader.EventID != 3 && pEventRecord->EventID != 4) return;

    // 解析事件数据(需参考Microsoft-Windows-FileIO的事件schema实现)
    const char* fileName = "..."; // 提取文件名
    long long offset = ...;       // 提取读写偏移量
    long long bytes = ...;        // 提取读写字节数

    // 调用Java方法传递监控数据
    JNIEnv* env;
    g_jvm->AttachCurrentThread((void**)&env, NULL);
    jclass cls = env->FindClass("com/example/FileIOMonitor");
    jmethodID mid = env->GetStaticMethodID(cls, "onFileIOEvent", "(Ljava/lang/String;JJ)V");
    jstring jFileName = env->NewStringUTF(fileName);
    env->CallStaticVoidMethod(cls, mid, jFileName, offset, bytes);
    env->DeleteLocalRef(jFileName);
    g_jvm->DetachCurrentThread();
}

// JNI初始化方法
JNIEXPORT void JNICALL Java_com_example_FileIOMonitor_startMonitoring(JNIEnv* env, jclass cls) {
    env->GetJavaVM(&g_jvm);
    // 初始化ETW会话、注册提供者、启动追踪(具体实现参考Windows ETW API文档)
}

Java对应代码

public class FileIOMonitor {
    static {
        System.loadLibrary("FileIOMonitorJNI");
    }

    public static native void startMonitoring();

    public static void onFileIOEvent(String fileName, long offset, long bytes) {
        // 处理实时监控事件
        System.out.printf("文件: %s | 偏移量: %d | 字节数: %d%n", fileName, offset, bytes);
    }

    public static void main(String[] args) {
        startMonitoring();
        // 保持进程运行
        while (true) {
            try { Thread.sleep(1000); } catch (InterruptedException e) {}
        }
    }
}
  • 事件结构可通过wevtutil gp Microsoft-Windows-FileIO /e查看
  • 需依赖Windows SDK和C++编译环境

方案对比

方案复杂度依赖实时性
PowerShell+ETW低PowerShell、Jackson秒级延迟(符合需求)
JNI+ETW API中C++编译环境、Windows SDK亚秒级延迟

注意事项

  • 两种方案均需管理员权限运行,因为ETW系统级事件需要权限
  • 可通过ETW查询语句进一步过滤事件(如排除特定路径)
  • 已通过EventID过滤创建/删除事件,无需额外处理

内容的提问来源于stack exchange,提问作者JayC667

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:07:34