How do I read a user-specified file in an emscript

2019-02-21 22:06发布

问题:

I'm currently working on a file parsing library in C with emscripten compile support. It takes a file path from the user where it reads the binary file and parses it.

I understand that emscripten doesn't support direct loading of files, but instead uses a virtual filesystem. Is there any way to load the file at the given path into the virtual filesystem so that the emscripten compiled C lib can read it? I'm looking for solutions for both NodeJS and in the browser.

回答1:

If you want compile this file directly into library you can use --preload-file or --embed-file option. Like this:

emcc main.cpp -o main.html --preload-file /tmp/my@/home/caiiiycuk/test.file

After that in C you can open this file normally:

fopen("/home/caiiiycuk/test.file", "rb")

Or you can use emscripten javascript fs-api, for example with ajax:

$.ajax({
    url: "/dataurl",
    type: 'GET',
    beforeSend: function (xhr) {
        xhr.overrideMimeType("text/plain; charset=x-user-defined");
    },
    success: function( data ) {
        Module['FS_createDataFile']("/tmp", "test.file", data, true, true);
    }
});

After that you can open this file from C. Also it is not best way to pass data into C code, you can pass data directly in memory, read about this.



回答2:

If you can provide a file via a form upload from your webpage, then on receiving the file upload "data" you can do something like this.

Refer here on how to achieve this

Sample code for your problem could be:

// Assuming data contains the base64 encoded fileData,
// you want the file to be present at "." location with name as myFileName
Module['FS_createDataFile'](".", myFileName, atob(data), true, true);

The detailed explanation of API used can be found here

This solution works for browsers where you do not have direct access to file system



回答3:

You can also use a synchronous virtual XHR backed file. Beware that it requires that you execute your code in a web worker. If you want to support multiple files, you can access them using a virtual file system for an archive. The major plus of this approach is that it will defer loading until the file is actually read.



回答4:

Emscripten, as of today (June 2016), supports a filesystem called NODEFS which provides access to the local file-system when running on nodejs.

You need to manually mount the NODEFS filesystem into the root filesystem. For example:

EM_ASM(
  FS.mkdir('/working');
  FS.mount(NODEFS, { root: '.' }, '/working');
);

You can then access ./abc from the local filesystem via the virtual path /working/abc.