2013-08-19 3 views
2

Док для readableStream.read(size) говорит,читаемой записи потока не возвращает нуль

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

Чтобы проверить это я сделал:

// in test.js 
process.stdin.on('readable', function(){ 
    var d = this.read(30); 
    if (d) console.log(d.toString()); 
}); 

$ (echo abc; sleep 1; echo def; sleep 1; echo ghi) | node test.js 

Выход был следующим:

abc 
def 
ghi 

Я ожидал, что код для печати null, как size(30) было больше, чем записанных байтов. Почему он не печатает null?

Согласно комментариям @ hexacyanide, я переписал код, как показано ниже, и снова запускали тест: выход

process.stdin.on('readable', function() { 
    var d = this.read(300); 
    if (d === null) { 
    console.log("NULL") 
    } else { 
    console.log(d.toString()); 
    } 
}); 

process.stdin.on('end', function() { 
    console.log('END EVENT') 
}); 

Тест:

NULL 
NULL 
NULL 
abc 
def 
ghi 

END EVENT 

теперь я могу понять, выход до 3 NULL's.
После этого у меня есть несколько вопросов, основанных на выходе:

  1. Почему я получаю abc\ndef\nghi как выход для моего первого теста? Я спрашиваю об этом, потому что даже после нажатия abcdefghi на поток длина его буфера равна 9. Поэтому, если я прочитал какое-либо время, операция чтения должна вернуть null. Разумеется, я установил размер чтения в 300.
  2. Как поток знает, что я выполнил все мои нажатия?
+0

Есть ли у вас код для отображения? Используя вашу настройку, я провел несколько тестов, а 'd' -« null », как и ожидалось. Обратите внимание, что вы не должны ожидать, что 'null' будет напечатан, из-за вашего оператора' if'. Протестировано на NodeJS 'v0.10.16'. – hexacyanide

+0

вы должны проверить на 'null', используя' if (d === null) ' – vinayr

+0

@hexacyanide, я обновил вопрос в соответствии с вашими комментариями. Пожалуйста, взгляните на это. vinayr, Спасибо за ваш совет, я также включил ваш нулевой код проверки в обновленный вопрос – rajkamal

ответ

1

При попытке воспроизвести вашу проблему я предположил, что вы уже возобновили поток process.stdin, который по умолчанию приостановлен. Позже я узнал, что, покидая этот бит, я получил непреднамеренный вывод, который вы получали. Это то, что документация NodeJS гласит:

поток стандартного ввода паузы по умолчанию, поэтому необходимо позвонить process.stdin.resume() читать из него.

Перед добавлением readable слушателя, я просто использовал resume() на поток и получил предполагаемую продукцию.

Я не знаю, если я правильно, но в вашем случае, я бы предположить, что readable стреляет каждый раз echo запускается, и read() не читает ничего в тех случаях, но когда stdin закрыт, read() просто читает все.Вот мой тестовый код и результаты:

process.stdin.on('readable', function() { 
    console.log('fire'); 
    console.log(process.stdin.read(300)); 
}).on('end', function(){ 
    console.log("END EVENT") 
}); 

Я побежал этот код так: (echo abc; sleep 1; echo def; sleep 1; echo ghi) | node test.js и получил следующие результаты:

fire 
null 
fire 
null 
fire 
null 
fire 
<Buffer 61 62 63 0a 64 65 66 0a 67 68 69 0a> 
END EVENT 

При тестировании после возобновления stdin потока, readable пожаров в четыре раза, и read(300) правильно возвращает null.

+0

, спасибо большое за то, что нашли время. У меня есть одна заметка о вашем ответе. AFAIK Когда вы вызываете возобновление или паузу в потоке, он переходит в текущий режим, создавая этот поток, чтобы испускать только событие данных, а не читаемое событие. На вопрос, я понял до 3-го «пожара». как было возможно, чтобы узел мог прочитать поток после третьего события «огонь», поскольку поток еще не заполнен 300 байтами. – rajkamal

+0

+1, для объяснения. Извините, я не мог отметить это как ответ. – rajkamal