读取大文件和拆分方法



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

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

我可以像这样将文件读入流:

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

但是,我似乎不知道如何处理文件并提取我需要的数据。

这里有三个问题。

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

首先需要读取每个文件的内容。注意,包裹的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-----

应该导致:

[ 'nMIIEzDCCArSgAwIBAgIVCugKYzMN5ra8zPWxYE8pUU9SxjYSMA0GCSqGSIb3DQEBnCwUAMHAxCzAJBgNVBAYTAkdCMRUwEwYDVQQIDAxXYXJ3aWNrc2hpcmUxEDAOBgNVnBAcMB1dhcndpY2sxEDAOBgNVBAoMB0VudHJ1c3QxETAPBgNVBAsMCFBLSSBURUFNn'
, 'nMIIETzCCAjegAwIBAgIVBShP2Mx74DZEyNKwYZZPGntRmSWnMA0GCSqGSIb3DQEBnDQUAMHIxCzAJBgNVBAYTAkdCMRUwEwYDVQQIDAxXYXJ3aWNrc2hpcmUxEDAOBgNVnBAcMB1dhcndpY2sxDDAKBgNVBAoMA0lCTTERMA8GA1UECwwIUEtJIFRFQU0xGTAXn5/62n'
]

为了得到这个结果,我使用正则表达式,其中两个非匹配组用于分隔符,一个匹配组用于数据。首先提取分隔的块,然后删除分隔符。这可能不是很有效,但应该可以完成工作。

注意flatMap的回调将返回一个字符串数组。在这里使用map将产生一个数组流——每个文件一个。我们想要的是一个字符串流。这就是为什么这里使用flatMap '。

最后,您需要让流流动起来并从中获取数据。要做到这一点,您需要调用流上的消费方法。在这个例子中,我使用toArray。提供给这个方法的回调函数将被一个包含流的所有元素的数组调用——在这个例子中是你所有的数据块。

全文如下:

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
  )

相关内容

  • 没有找到相关文章

最新更新