我试图在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-----')
但是,我似乎不知道如何处理文件并提取我需要的数据。
这里有三个问题。
- 从文件读取内容数据
- 提取分隔块
- 从流中获取结果数据
首先需要读取每个文件的内容。注意,包裹的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
)