【问题标题】:File written to createWriteStream gets corrupted when listening to 'data' event on createReadStream in NodeJS在 NodeJS 中的 createReadStream 上侦听“数据”事件时,写入 createWriteStream 的文件已损坏
【发布时间】:2018-05-17 05:48:13
【问题描述】:

我有一个 Electron 应用程序,并且我已经编写了一个使用 Node 的 fs 模块复制文件的服务。当不听fs.createReadStreamdata 事件时,文件复制工作正常,但是当我添加readStream.on('data', ... 事件时,输出文件被损坏(输出文件的大小总是小于原始文件)。这是我复制文件的功能代码:

copyFile(sourcePath: string, targetPath: string): Observable<FileCopyResponseModel> {
        const copyResponse = new Subject<FileCopyResponseModel>();
        const fileSize = this.node.fs.statSync(sourcePath).size;
        const readStream = this.node.fs.createReadStream(sourcePath);
        let bytesCopied = 0;

        readStream.once("error", (err) => {
            const response = new FileCopyResponseModel();
            response.is_error = true;
            response.error = err;
            copyResponse.next(response);
        });

        readStream.on('data', (buffer) => {
            bytesCopied+= buffer.length

            const response = new FileCopyResponseModel();
            response.is_error = false;
            response.is_done = false;
            response.size = fileSize;
            response.size_copied = bytesCopied;
            copyResponse.next(response);
        });

        this.node.mkdirp(this.node.path.dirname(targetPath), (err) => {
            if (err) {
                const response = new FileCopyResponseModel();
                response.is_error = true;
                response.error = err;
                copyResponse.next(response);
            } else {
                const writeStream = this.node.fs.createWriteStream(targetPath);
                writeStream.once("error", (err) => {
                    const response = new FileCopyResponseModel();
                    response.is_error = true;
                    response.error = err;
                    copyResponse.next(response);
                });

                writeStream.once("close", (ex) => {
                    const response = new FileCopyResponseModel();
                    response.is_error = false;
                    response.is_done = true;
                    response.size = fileSize;
                    copyResponse.next(response);
                });

                readStream.pipe(writeStream);
            }
        });

        return copyResponse;
    }

如果我只是注释掉这部分代码,文件就会被正确复制:

readStream.on('data', (buffer) => {
            bytesCopied+= buffer.length

            const response = new FileCopyResponseModel();
            response.is_error = false;
            response.is_done = false;
            response.size = fileSize;
            response.size_copied = bytesCopied;
            copyResponse.next(response);
        });

知道这里有什么问题吗?

在旁注中,收听data 事件时正确报告复制进度。

【问题讨论】:

    标签: node.js electron fs


    【解决方案1】:

    我认为您正在尝试使用可读流两次。一次在on('data', 处理程序中,一次在readStream.pipe(writeStream); 中。 on('data', 将消耗可读流,然后您可以将其通过管道传输到写入流。

    你可以试试换行:

    readStream.pipe(writeStream);
    

    readStream.on('data', (buffer) => {
         bytesCopied+= buffer.length
    
         const response = new FileCopyResponseModel();
         response.is_error = false;
         response.is_done = false;
         response.size = fileSize;
         response.size_copied = bytesCopied;
         copyResponse.next(response);
         // new bit
         writeStream.write(buffer);
     });
    

    并从上面的处理程序中删除on('data,

    您也可以在读取流结束时结束 writeStream。

    readStream.on('end', function() {
        console.log('end');
        writeStream.end();
    });
    

    【讨论】:

    • 在这种情况下我们将如何关闭 writeStream?
    猜你喜欢
    • 2014-01-09
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 2013-10-24
    • 2023-03-20
    • 2019-01-09
    相关资源
    最近更新 更多