阅读大文件和splitby方法

我试图使用highland.jssplitby方法来提取开始和结束分隔符之间的数据。

  -----BEGIN DATA----- MIIEzDCCArSgAwIBAgIVCugKYzMN5ra8zPWxYE8pUU9SxjYSMA0GCSqGSIb3DQEB CwUAMHAxCzAJBgNVBAYTAkdCMRUwEwYDVQQIDAxXYXJ3aWNrc2hpcmUxEDAOBgNV BAcMB1dhcndpY2sxEDAOBgNVBAoMB0VudHJ1c3QxETAPBgNVBAsMCFBLSSBURUFN -----END DATA----- -----BEGIN DATA----- MIIETzCCAjegAwIBAgIVBShP2Mx74DZEyNKwYZZPGntRmSWnMA0GCSqGSIb3DQEB DQUAMHIxCzAJBgNVBAYTAkdCMRUwEwYDVQQIDAxXYXJ3aWNrc2hpcmUxEDAOBgNV BAcMB1dhcndpY2sxDDAKBgNVBAoMA0lCTTERMA8GA1UECwwIUEtJIFRFQU0xGTAX 5/62 -----END DATA----- 

我可以将文件读入如下的stream中:

  const readFile = _.wrapCallback(fs.readFile); stream = _(files).map(readFile).parallel(2); const blob = _(stream).splitBy('-----BEGIN DATA-----') 

但是,我似乎无法解决如何处理文件并提取我需要的数据。

这里真的有三个问题。

  1. 从文件中读取内容数据
  2. 提取分隔的块
  3. 从stream中获取结果数据

首先你需要阅读每个文件的内容。 请注意,包装的readFile将发射Buffers ,而不是Strings 。 要提取块,您需要将每个文件的内容转换为一个String 。 我假设文件编码为utf-8

其次,您需要将数据与文本的其余部分分开。 我假设你只想在起始和结束分隔符之间使用大块,没有分隔符本身或者可能在分隔符之外的任何东西,例如:

 -----BEGIN DATA----- MIIEzDCCArSgAwIBAgIVCugKYzMN5ra8zPWxYE8pUU9SxjYSMA0GCSqGSIb3DQEB CwUAMHAxCzAJBgNVBAYTAkdCMRUwEwYDVQQIDAxXYXJ3aWNrc2hpcmUxEDAOBgNV BAcMB1dhcndpY2sxEDAOBgNVBAoMB0VudHJ1c3QxETAPBgNVBAsMCFBLSSBURUFN -----END DATA----- junky junk junk -----BEGIN DATA----- MIIETzCCAjegAwIBAgIVBShP2Mx74DZEyNKwYZZPGntRmSWnMA0GCSqGSIb3DQEB DQUAMHIxCzAJBgNVBAYTAkdCMRUwEwYDVQQIDAxXYXJ3aWNrc2hpcmUxEDAOBgNV BAcMB1dhcndpY2sxDDAKBgNVBAoMA0lCTTERMA8GA1UECwwIUEtJIFRFQU0xGTAX 5/62 -----END DATA----- 

应该导致:

 [ '\nMIIEzDCCArSgAwIBAgIVCugKYzMN5ra8zPWxYE8pUU9SxjYSMA0GCSqGSIb3DQEB\nCwUAMHAxCzAJBgNVBAYTAkdCMRUwEwYDVQQIDAxXYXJ3aWNrc2hpcmUxEDAOBgNV\nBAcMB1dhcndpY2sxEDAOBgNVBAoMB0VudHJ1c3QxETAPBgNVBAsMCFBLSSBURUFN\n' , '\nMIIETzCCAjegAwIBAgIVBShP2Mx74DZEyNKwYZZPGntRmSWnMA0GCSqGSIb3DQEB\nDQUAMHIxCzAJBgNVBAYTAkdCMRUwEwYDVQQIDAxXYXJ3aWNrc2hpcmUxEDAOBgNV\nBAcMB1dhcndpY2sxDDAKBgNVBAoMA0lCTTERMA8GA1UECwwIUEtJIFRFQU0xGTAX\n5/62\n' ] 

为了得到这个结果,我使用正则expression式和两个不匹配的分隔符组以及一个匹配的数据组。 首先,我提取分隔的块,然后删除分隔符。 这可能不是很有效率,但应该做的工作。

请注意, flatMap的callback将返回一个string数组。 在这里使用map将导致数组stream – 每个文件一个。 我们想要的是一串string。 这就是为什么在这里使用flatMap的原因。

最后,您需要获取stream,并从中获取数据。 要做到这一点,你需要调用stream的消费方法。 在这个例子中我使用toArray 。 提供给这个方法的callback函数将被一个包含stream的所有元素的数组调用 – 在这种情况下,所有的数据块都将被调用。

这是完整的东西:

 const Stream = require("highland") const FS = require("fs") const files = [ "./input-1.txt", "./input-2.txt" ] const readFile = Stream.wrapCallback(FS.readFile); const pattern = /(?:-----BEGIN DATA-----)((.|\n)+?)(?:-----END DATA-----)/gm Stream(files) // 1. Read contents .map(readFile) .parallel(2) .invoke("toString", ["utf-8"]) // 2. Process contents to extract data .flatMap((content) => content // get an array of chunks (including delimiters) .match(pattern) // remove the delimiters from each chunk, leaving only the data .map((chunk) => chunk.replace(pattern, "$1"))) // 3. Get the resulting data out of the stream .toArray((chunks) => console.log(chunks) // will print an array of data chunks )