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

WASM平台fopen无法读取本地文件,求无需--preload-file的解决方案

问题描述

我用emcc编译了以下C代码:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    if(argc > 2 || argc < 2) {
        printf("\nEnter the name of file \n");
        return 0;
    }
    FILE *file = NULL;
    // Open file in read mode
    printf("file name: %s",argv[1]);
    file = fopen(argv[1], "r");
    if(file != NULL) {
        printf("\nFile is successfully open\n");
    }
    else {
        printf("\nFile is not opening\n");
        return 0;
    }
    fclose(file);
    return 0;
}

直接编译运行:

$emcc mycode.c
$node mycode.js input.txt

输出:

file name: input.txt
File is not opening 

用--preload-file编译可以成功:

$emcc mycode.c --preload-file input.txt -o mycode.html
$node mycode.js input.txt

输出:

file name: input.txt
File is successfully open

但我不想在编译时指定文件名,希望能直接通过fopen读取本地文件系统中的文件,请问有什么方法?

解决方案

Emscripten默认使用内存文件系统(MEMFS),无法直接访问本地文件系统。要实现动态读取本地文件,需要启用NODEFS(Node.js文件系统)挂载本地目录,具体步骤如下:

1. 修改C代码,初始化NODEFS挂载

引入<emscripten.h>,通过EM_ASM宏将本地目录挂载到Emscripten的虚拟文件系统中:

#include <stdio.h>
#include <string.h>
#include <emscripten.h>

int main(int argc, char *argv[])
{
    if(argc != 2) {
        printf("\nEnter the name of file \n");
        return 0;
    }

    // 挂载当前本地目录到Emscripten文件系统的/local路径下
    EM_ASM(
        FS.mkdir('/local');
        FS.mount(NODEFS, { root: '.' }, '/local');
    );

    FILE *file = NULL;
    printf("file name: %s\n", argv[1]);

    // 拼接挂载路径,访问本地文件
    char local_path[256];
    snprintf(local_path, sizeof(local_path), "/local/%s", argv[1]);
    file = fopen(local_path, "r");

    if(file != NULL) {
        printf("File is successfully open\n");
        fclose(file);
    } else {
        printf("File is not opening\n");
        return 0;
    }
    return 0;
}

2. 编译时启用NODEFS

编译时添加-s NODERAWFS=1选项,允许Emscripten调用Node.js的原生文件系统API:

emcc mycode.c -s NODERAWFS=1 -o mycode.js

3. 运行代码

直接用Node.js运行,传入本地文件名即可:

node mycode.js input.txt
补充说明
  • NODEFS仅适用于Node.js环境,浏览器环境无法直接访问本地文件系统
  • 可以修改FS.mount中的root参数指定任意本地目录(比如/home/user/docs)
  • 如果想直接用文件名而不用拼接路径,可将本地目录挂载到Emscripten虚拟文件系统的根目录:
    FS.mount(NODEFS, { root: '.' }, '/');
    
    之后直接用fopen(argv[1], "r")就能访问本地文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 13:08:06