Получение заголовков CSV без чтения всего потока - PullRequest
1 голос
/ 13 июня 2019

Я использую модуль узла csv-parser для захвата заголовков потоковых CSV-файлов; Я использую источник событий 'headers', который встроен в модуль.

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

Каков наилучший способ сделать это? Я пробовал несколько разных методов, включая .destroy(), но я не нашел решение, которое работает. Может быть, я пытаюсь закрыть поток в неправильном месте? Вот что у меня есть:

function getHeaders(dataStream) {
    return new Promise((resolve, reject) => {
        dataStream
            .pipe(csv())
            .on('headers', (headers) => {
                let headerArray = Array.prototype.slice.call(headers);
                resolve(headerArray);                
                dataStream.destroy();
            })
            .on('error', (err) => {
                reject(`err from readingFile ${err}`)
            })          
    });
}

1 Ответ

0 голосов
/ 20 июня 2019

Как насчет чтения первых 2 строк потока, а затем передачи массива в csv как читаемый поток?

Попробуйте это:

const lineReader = require('readline');
const Stream = require('stream')

function getHeaders(dataStream) {
    return new Promise((resolve, reject) => {
       let wantedLines = [];
       lineReader.createInterface({
         input: dataStream
       });
       lineReader.on('line', (line) => {
         if(wantedLines.length >= 2) {
           lineReader.close();
         }
       });
       lineReader.on('close', () => {
          let resolved = false;
          const readableStream = new Stream.Readable();
          readableStream
            .pipe(csv())
            .on('headers', (headers) => {
              if (!resolved) resolved = true;
              resolve(headers);
            })
            .on('error', reject);
            .on('close', () => {
              if (!resolved) resolve([]);
            });
          wantedLines.forEach(line => readableStream.push(line));
          readableStream.destroy();
       });
    });
}

Не проверял, прокомментируйте, если что-то не так.

...