2015-02-26 16 views
8

Wyobraź sobie, że masz wiele długich plików tekstowych, i musisz wyodrębniać tylko dane z pierwszego wiersza każdego z nich (bez czytania dalszych treści). Jaki jest najlepszy sposób w Node JS, aby to zrobić?Jaki jest najskuteczniejszy sposób czytania tylko pierwszego wiersza pliku w węźle JS?

Dzięki!

+1

można wywołać polecenie 'head' na plikach z poziomu węzła? korzystaj z funkcji pliku/systemu operacyjnego, dla których są one dobre. :) – TZHX

+1

Kod, którego potrzebuję, jest częścią biblioteki, która może być używana w dowolnym systemie operacyjnym obsługującym węzeł JS, więc lepiej byłoby zrobić to za pomocą samego węzła. Jeśli się nie mylę, "głowa" nie jest dostępna na przykład w systemie Windows. – Pensierinmusica

+0

musisz wiedzieć, jak długo trwa ta pierwsza linia, ale możesz przeskoczyć i wczytać pierwszą, powiedzmy 5kb, a następnie podzielić 5kb za pomocą linii, zachowując tylko pierwszą. użyj fs.read() zamiast fs.readFile(): http://nodejs.org/api/fs.html#fs_fs_read_fd_buffer_offset_length_position_callback – dandavis

Odpowiedz

6

skończyło się na przyjęcie tego rozwiązania, co wydaje się najbardziej wydajnych widziałem do tej pory:

var fs = require('fs'); 
var Q = require('q'); 

function readFirstLine (path) { 
    return Q.promise(function (resolve, reject) { 
    var rs = fs.createReadStream(path, {encoding: 'utf8'}); 
    var acc = ''; 
    var pos = 0; 
    var index; 
    rs 
     .on('data', function (chunk) { 
     index = chunk.indexOf('\n'); 
     acc += chunk; 
     index !== -1 ? rs.close() : pos += chunk.length; 
     }) 
     .on('close', function() { 
     resolve(acc.slice(0, pos + index)); 
     }) 
     .on('error', function (err) { 
     reject(err); 
     }) 
    }); 
} 

stworzyłem moduł npm Dla wygody, o nazwie „firstline”.

Dzięki @dandavis za sugestię użycia String.prototype.slice()!

+0

ciekawe, jak duże jest każde _chunk_? – dandavis

+0

@dandavis, 64 kb – Pensierinmusica

+1

dzięki za powrót. brzmi tak, jakbym musiał ponownie poprawić mój własny rozmiar bufora i zmienić moją własną rada ... zaoferowałbym to dla bardzo dużej prędkości (jeśli to jest ważne), byłoby szybciej użyć 'acc.slice (0, acc.indexOf (" \ n "))' na zdarzeniu close zamiast podziału całego 64kb + lub nawet jakoś przekazać indeks z zdarzenia danych (plus długość acc) dla wydajności bare-metal. – dandavis

1

// Tu idziesz;

var lineReader = require('line-reader'); 
var async = require('async'); 

exports.readManyFiles = function(files) { 
    async.map(files, 
     function(file, callback)) 
      lineReader.open(file, function(reader) { 
       if (reader.hasNextLine()) { 
       reader.nextLine(function(line) { 
        callback(null,line); 
       }); 
       } 
      }); 
     }, 
     function(err, allLines) { 
      //do whatever you want to with the lines 
     }) 
} 
Powiązane problemy