2014-02-04 6 views
5
var fs = require('fs'); 

var file = fs.createReadStream('./zeros.txt'); 
var dataSize = 0; 

file.on('readable', function() { 
    var data = file.read(10); 
    console.log('readable size = ', data.length); 
    console.log(data.toString()); 
}); 

Thie файл «zeros.txt» содержит 700 символов «0»«читаемым» событие происходит дважды

Как я понимаю, после вызова чтения (10), поток должен остановиться и ждать нового чтения () вызов. Тем не менее, результат вызова:

readable size = 10 
0000000000 
readable size = 10 
0000000000 

ответ

8

После Node.js загрузит файл (все или только часть, зависит от размера самого файла) в буфер (с помощью метода нажима()) его будет излучать readable event, чтобы указать, что некоторые данные были прочитаны в буфере и готовы к использованию. Затем после того, как вы позвоните read(10), вы освободите буфер, а затем Node.js снова заполнит буфер и снова испустит readable event, чтобы указать, что все еще есть данные для чтения из буфера. Если вы позвоните по номеру read(700), то последующие readable event не будут выбрасываться снова.

Flowing- и непроточного Режим

В отличие при прослушивании для data event поток будет оставаться в так называемом, не пропуская режиме. Это означает, что разработчик будет отвечать за освобождение потока (чтение из потока). С другой стороны, при прослушивании data event поток автоматически включается в так называемый потоковый режим, что означает, что сам поток будет нести ответственность за освобождение себя, т. Е. Поток будет заполняться и опустошаться до базовой системы (в этом случае zero.txt будут полностью прочитаны). Обратите внимание, что буфер будет заполнен данными автоматически в любом режиме.

адаптированном

Пример из режима непроточного, где мы должны очистить буфер вручную (используя read() метод):

var fs = require('fs'), 
util = require('util'); 

// I have increased the file size to 19 MB (about 19 mln characters); 
// Cause of the buffer capicity. 
var file = fs.createReadStream('./zeros.txt'); 
var dataSize = 0; 

// Readable will be called when the buffer has been filled with data. 
// Initially Node.js will fill the buffer with data automatically, 
// so this event will be called automatically aswell of course. 
// Once the buffer will be free again after the first fill, Node.js 
// will fill the buffer automatically again. Node.js just watches this stream 
// and makes sure to fill it, when there is still some unread data in the zero.txt file. 
file.on('readable', function() { 
var i = 0; // we will count how many times did while loop, for fun 

// If the buffer will be empty Node will write data to the buffer 
// automatically, we don't have to care about that. However 
// you can specify the buffer capicty manually if you want. 
console.log('loading more data from the underlying system'); 

// This will make the stream read 1000 bytes 
// it will also return a value NULL if there is not enough 
// data to read from the buffer (meaning buffer has been fully read 
// or there is still some data but you are trying to read 1000 bytes 
// and there is less than 1000 bytes left) 
while(file.read(1000) !== null) { 
    i++; 
} 
// At this moment while loop has read everything from the buffer. 
// The buffer is now empty. After this comment console.log will execute 
// Node.js will fill the buffer again with new data automatically. 
// And then the 'readable' event will fire again. 
console.log("had to loop: " + i + " times before the buffer was empty"); 
}) 

Последние несколько результатов из консоли:

loading more data from the underlying system 
had to loop: 66 times before the buffer was empty 
loading more data from the underlying system 
had to loop: 65 times before the buffer was empty 
loading more data from the underlying system 
had to loop: 66 times before the buffer was empty 
loading more data from the underlying system 
had to loop: 46 times before the buffer was empty 
loading more data from the underlying system 
had to loop: 1 times before the buffer was empty 

режим непроточного

Это был нетекущий режим, так как нам нужно было освободить буфер вручную. Теперь мы перейдем к текущему режиму. Установка data event listener на Readable Stream переключает поток на flowing mode с начального non-flowing mode. Это означает, что буфер будет опустошен автоматически. Node.js передаст вам данные в качестве аргумента в data event listener, и после того, как эта функция выполнит буфер, снова будет пуст, и если все еще некоторые данные в базовом исходном буфере будут автоматически заполнены новыми данными, а затем событие данных будет снова испускать. ПРИМЕЧАНИЕ. Если вы слушаете событие data, и readable event оба будут стрелять, но data event listener будет сначала пустым буфером, а ТОГДА будет стрелять readable event, поэтому ваш read() всегда будет возвращать NULL.

var fs = require('fs'), 
util = require('util'); 

var file = fs.createReadStream('./zeros.txt'); 
var dataSize = 0; 

file.on('data', function() { 
    // Once this listener will stop executing new data will be read 
    // into the buffer and then the 'data' event will be emitted 
    // again. 
    console.log('data has been loaded and emptied!') 
}) 

file.on('readable', function() { 
    // Notice we want to try to read 1 byte from the buffer 
    // but in the console we see that the read() method 
    // resulted in NULL, which means that the buffer is empty. 
    // That's of course because we enterd the flowing mode 
    // by setting up the 'data' event. (In flowing mode) 
    // after the execution of the 'data' event all data 
    // from the buffer will be read, but the execution 
    // of listeners will continue. After all the event listeners 
    // attached to this stream will execute, Node.js will fill 
    // the buffer automatically again. 
    console.log('readable ' + file.read(1)) 
}); 

Последние несколько результатов из консоли:

data has been loaded and emptied! 
readable null 
data has been loaded and emptied! 
readable null 
data has been loaded and emptied! 
readable null 
data has been loaded and emptied! 
readable null 
data has been loaded and emptied! 
readable null 
1

Мой ответ основан на версии 0.12.4.

1: Каждый read(n) функция, которая протягивается от Stream.Readable вызовет внутреннюю _read(n) функцию, когда текущая внутренняя длина буфера равна 0 или меньше, чем значение highWaterMark собственности.

2: readable события будет срабатывать только тогда, когда текущая внутренняя длина буфера равна 0 или данные, считанные из внутреннего буфера равно нуля или нулевой показателя произошел.

Давайте рассмотрим ваш код в качестве примера, чтобы узнать, что произошло.

file.on('readable', function() { 

регистр readable события обработчика будет вызывать read(0) функции, чтобы загрузить данные из файла, чтобы внутренний буфер. Если вы не перезапишите значение highWaterMark, оно будет загружать максимум 64 * 1024 = 65535 кусков. В вашем коде он загрузил все данные из файла «zeros.txt». После этого он вызовет событие readable, так как длина внутреннего буфера равна 0 перед вызовом функции read(0).

var data = file.read(10); 

В обработчике вы снова вызвали функцию read(10). Это также вызовет процесс загрузки из файла в буфер. Однако в это время данные не будут загружены. Поэтому null было бы нажато, чтобы указать, что процесс чтения был завершен. Второе событие readable было запущено. Именно по этой причине вы должны увидеть и увидеть только два события readable.

Если вы читаете файл размером более 65535 байт (почти 66 КБ), вы должны увидеть только одно событие readable.

Вы не должны писать readable обработчик события, как это, вы должны обратиться к следующему:

var chunk; 
while(null !== (chunk = fs.read())) { 
    //handle the chunk 
} 

Если вы хотите обрабатывать кусок на вашем пути, чтобы сделать некоторые специальные вещи, пожалуйста, позаботьтесь о правилах ; в противном случае программа будет оставаться в состоянии «паузы», больше данных не будет прочитано и больше данных не будет получено.

См. fs.ReadStream и stream.Readable.

Смежные вопросы