在NodeJS中的createReadStream上监听'data'事件时,写入createWriteStream的文件会被破坏

时间:2017-12-03 18:42:32

标签: node.js electron fs

我有一个Electron应用程序,我已经使用Node的fs模块编写了一个复制文件的服务。文件复制在没有收听data fs.createReadStream事件时工作正常,但是当我添加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事件时正确报告了复制进度。

1 个答案:

答案 0 :(得分:2)

我认为你试图两次使用可读流。进入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();
});