use-strict / 7z-wasm

7-Zip for JavaScript environments, compiled to WASM
Other
109 stars 7 forks source link

I cannot readFile inside Worker virtual file system #17

Closed xlmnxp closed 1 year ago

xlmnxp commented 1 year ago

Hello, I don't know what the issue but I get good progress using your library (I created: https://extractify.zip/ which is open source now :) ),

I have the following code inside Worker and it work great to extract the files and show them in files list but I cannot read any file (except the archive file it self)

The following debug for reading specific file inside the archive:

Logs: image

Code:

    async generateBlobUrl(file: iFile) {
        if (!this.sevenZip) return;
        file = typeof file === "string" ? JSON.parse(file) : file;

        this.sevenZip.FS.chdir("/");
        console.log("Directory content before extracting", this.sevenZip.FS.readdir("/"));

        // extract file from archive
        this.execute(['x', '-y', this.archiveName, file.path.substring(1)]);

        console.log("Directory content after extracting", this.sevenZip.FS.readdir('/'));

        console.log({
            file: file.path.substring(1),
            p: file.path
        });

        const stream = this.sevenZip.FS.open(file.path, 'r');
        const stat = this.sevenZip.FS.stat(file.path);
        const bufferLength = stat.size;
        const buffer = new Uint8Array(bufferLength);
        this.sevenZip.FS.read(stream, buffer, 0, bufferLength, 0);
        this.sevenZip.FS.close(stream);

        console.log({buffer});

        // const blob = new Blob([buffer], { type: mime.lookup(file.extension!) || "application/octet-stream" });
        // const blobUrl = URL.createObjectURL(blob);

        // console.log({blobUrl});

        return "blobUrl";
    }

The following debug for reading archive file (compressed file) inside the archive:

Logs: image

Code:

    async generateBlobUrl(file: iFile) {
        if (!this.sevenZip) return;
        file = typeof file === "string" ? JSON.parse(file) : file;

        // override archive name as file name
        file.path = '/' + this.archiveName;

        this.sevenZip.FS.chdir("/");
        console.log("Directory content before extracting", this.sevenZip.FS.readdir("/"));

        // extract file from archive
        this.execute(['x', '-y', this.archiveName, file.path.substring(1)]);

        console.log("Directory content after extracting", this.sevenZip.FS.readdir('/'));

        console.log({
            file: file.path.substring(1),
            p: file.path
        });

        const stream = this.sevenZip.FS.open(file.path, 'r');
        const stat = this.sevenZip.FS.stat(file.path);
        const bufferLength = stat.size;
        const buffer = new Uint8Array(bufferLength);
        this.sevenZip.FS.read(stream, buffer, 0, bufferLength, 0);
        this.sevenZip.FS.close(stream);

        console.log({buffer});

        // const blob = new Blob([buffer], { type: mime.lookup(file.extension!) || "application/octet-stream" });
        // const blobUrl = URL.createObjectURL(blob);

        // console.log({blobUrl});

        return "blobUrl";
    }
xlmnxp commented 1 year ago

after some debug, I found Virtual FS think the file isn't there, Is there any solution for the issue?

xlmnxp commented 1 year ago

the project: https://github.com/xlmnxp/extractify.zip

use-strict commented 1 year ago

Can you try this.sevenZip.FS.readFile(file.path) // -> Uint8Array instead of read+stat?

Also, what does this print?

let { node } = this.sevenZip.lookupPath("/");
console.log(node.contents);

If you expand the logged variable, it should be an object map with a key that corresponds to your mkv file. The value should have a contents property containing a non-empty Uint8Array.

xlmnxp commented 1 year ago

Can you try this.sevenZip.FS.readFile(file.path) // -> Uint8Array instead of read+stat?

Also, what does this print?

let { node } = this.sevenZip.lookupPath("/");
console.log(node.contents);

If you expand the logged variable, it should be an object map with a key that corresponds to your mkv file. The value should have a contents property containing a non-empty Uint8Array.

I tried this.sevenZip.FS.readFile and same error message, but I can see the file inside this.sevenZip.lookupPath with it Unit8Array :+1:

do you know why file open and read don't work in my case?

use-strict commented 1 year ago

The error could be due to file permissions, if the flags are preserved when the file is extracted. See https://emscripten.org/docs/api_reference/Filesystem-API.html#FS.chmod

In any case, it's not a problem with 7z, but something Emscripten related.

xlmnxp commented 1 year ago

The error could be due to file permissions, if the flags are preserved when the file is extracted. See https://emscripten.org/docs/api_reference/Filesystem-API.html#FS.chmod

In any case, it's not a problem with 7z, but something Emscripten related.

you mean I will need to modify the file permissions before reading it? how I can do that if I don't have permission to read it at first place xD

use-strict commented 1 year ago

Try FS.chmod(file.path, 0700). See linked docs from previous comment

xlmnxp commented 1 year ago

Try FS.chmod(file.path, 0700). See linked docs from previous comment

you right, I tried this.sevenZip.FS.chmod(file.path, 0o777); after extracting and it solve the issue :+1: