代码之家  ›  专栏  ›  技术社区  ›  frank-dspeed

如何在NodeJS中从多个输入流读取时写入单个文件

  •  0
  • frank-dspeed  · 技术社区  · 6 年前

    如何在使用NodeJS从不同位置读取同一文件的多个输入流时写入一个文件。

    我想为下载使用更多的性能让我们假设我们有两个位置为同一个文件每个只能执行10mb的下游,所以我想从第一个位置和第二个位置并行下载一部分。用20mb来获得它。

    所以两个流都需要加入一些方式,两个流都需要知道它们正在下载的范围。

    我有两个例子

    var http = require('http')
    var fs = require('fs')
    
    // will write to disk __dirname/file1.zip
    function writeFile(fileStream){
      //...
    }
    // This example assums downloading from 2 http locations
    http.request('http://location1/file1.zip').pipe(writeFile)
    http.request('http://location2/file1.zip').pipe(writeFile)
    
    var fs = require('fs')
    
    // will write to disk __dirname/file1.zip
    function writeFile(fileStream){
      //...
    }
    
    // this example is reading the same file from 2 diffrent disks
    fs.readfFile('/mount/volume1/file1.zip').pipe(writeFile)
    fs.readfFile('/mount/volume2/file1.zip').pipe(writeFile)
    

    ReadStream需要在重新读取每个文件的下一个块之前检查定义的内容范围是否已经写入,并且可能应该从文件中的随机位置开始读取。

    如果文件内容的总长度是X,我们将它分成更小的块,并创建一个映射,其中每个条目都有一个固定的内容长度,这样我们就知道我们得到了哪些部分,我们总共下载了哪些部分。

    我们可以试着简单乐观地提高阅读能力

    let SIZE = 64; // 64 byte intervals
    let buffers = []
    let bytesRead = 0  
    
    function readParallel(filepath,callback){
    fs.open(filepath, 'r', function(err, fd) {
      fs.fstat(fd, function(err, stats) {
        let bufferSize = stats.size;
    
    
        while (bytesRead < bufferSize) {
          let size = Math.min(SIZE, bufferSize - bytesRead);
          let buffer = new Buffer(size),
          let position = bytesRead
          let length = size
          let offset = bytesRead
    
    
          let read = fs.readSync(fd, buffer, offset, length, position);
          buffers.push(buffer);  
          bytesRead += read;
        }
    
      });
    });
    }
    // At the End: buffers.concat() ==== "File Content"
    

    let f = fs.createReadStream("myfile.txt", {start: 1000});
    

    也可以使用 fs.open() fs.read() 然后可以将该文件描述符传递到 fs.createReadStream() 作为一个选项,流将以该文件描述符和位置开始(尽管显然 start 选择 fs.createReadStream()

    0 回复  |  直到 6 年前
        1
  •  0
  •   Avraham    6 年前

    csv-parse 具有 csv-stringify CSV Project

    const fs = require('fs');
    const parse = require('csv-parse');
    const stringify = require('csv-stringify')
    
    const stringifier = stringify();
    const writeFile = fs.createWriteStream('out.csv');
    
    fs.createReadStream('file1.csv').pipe(parse()).pipe(stringifier).pipe(writeFile);
    fs.createReadStream('file2.csv').pipe(parse()).pipe(stringifier).pipe(writeFile);
    

    在这里,我分别解析每个文件(使用不同的 parse 每个源的流),然后通过管道将两者连接到同一个源 stringify 将它们连接起来,然后写入目的地的流。