чтение большого файла и метод splitby

Я пытаюсь использовать этот splitbyметод highland.jsдля извлечения данных между разделителями начала и конца.

        -----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-----')

Тем не менее, я не могу понять, как обрабатывать файл и извлекать нужные мне данные.

javascript,node.js,stream,highland.js,

1

Ответов: 1


1

Здесь есть три проблемы.

  1. Чтение данных контента из файлов
  2. Извлечение разделенных фрагментов
  3. Получение полученных данных из потока

Сначала вам нужно прочитать содержимое каждого файла. Обратите внимание, что обернутый readFileбудет испускать Buffers, а не Strings. Чтобы извлечь куски, вам нужно преобразовать содержимое каждого файла в a String. Я предполагаю, что файлы закодированы как utf-8.

Во-вторых, вам нужно отделить данные от остальной части текста. Я предполагаю, что вам нужны только фрагменты между разделителями начала и конца, без самих разделителей или всего, что может быть за пределами разделителей, например:

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

должно привести к:

[ '
MIIEzDCCArSgAwIBAgIVCugKYzMN5ra8zPWxYE8pUU9SxjYSMA0GCSqGSIb3DQEB
CwUAMHAxCzAJBgNVBAYTAkdCMRUwEwYDVQQIDAxXYXJ3aWNrc2hpcmUxEDAOBgNV
BAcMB1dhcndpY2sxEDAOBgNVBAoMB0VudHJ1c3QxETAPBgNVBAsMCFBLSSBURUFN
'
, '
MIIETzCCAjegAwIBAgIVBShP2Mx74DZEyNKwYZZPGntRmSWnMA0GCSqGSIb3DQEB
DQUAMHIxCzAJBgNVBAYTAkdCMRUwEwYDVQQIDAxXYXJ3aWNrc2hpcmUxEDAOBgNV
BAcMB1dhcndpY2sxDDAKBgNVBAoMA0lCTTERMA8GA1UECwwIUEtJIFRFQU0xGTAX
5/62
'
]

Для получения этого результата я использую регулярное выражение с двумя несогласованными группами для разделителей и подходящей группой для данных. Сначала я извлекаю разделенные фрагменты, а затем удаляю разделители. Это может быть не очень эффективным, но должно выполнять эту работу.

Обратите внимание, что обратный вызов 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-----)((.|
)+?)(?:-----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
  )
JavaScript, Node.js, ручей, highland.js,