2017-12-03 5 views
0

Electronアプリケーションがあり、ノードのfsモジュールを使用してファイルをコピーするサービスを作成しました。 dataイベントを聞いていないときはファイルコピーが正常に機能しますが、​​イベントを追加すると、出力ファイルが破損してしまいます(出力ファイルのサイズは常に元のファイルサイズより小さくなります)。ここで間違っているものをNodeJSのcreateReadStreamで 'data'イベントを受信すると、createWriteStreamに書き込まれたファイルが破損する

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); 
     }); 

任意のアイデア:私はちょうどこのコードのセクションをコメントアウトした場合、正しく

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; 
    } 

ファイルをコピーされます:これは、ファイルをコピーするために私の機能コードのですか?

dataイベントを聞いているときに、コピーの進行状況が正しく報告されています。

答えて

1

私はあなたが読めるストリームを2回消費しようとしていると思います。 on('data',ハンドラに1回、readStream.pipe(writeStream);に1回。 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(); 
}); 
+0

この場合、writeStreamをどのように閉じますか? –

+0

私はどのように – willwoo

+0

はい、これが問題を解決したかを示す答えを更新しました。ありがとう。 –

関連する問題