2013-11-14 1 views
4

Я использую node.js и считываю ввод из последовательного порта, открывая файл/dev/tty, я отправляю команду и читаю результат команды, и я хочу закрыть поток после того, как прочитал и проанализировал все данные. Я знаю, что я закончил считывание данных маркером данных и их окончанием. Я нахожу, что как только я закрыл поток, моя программа не закончится.Как закрыть поток, который не имеет больше данных для отправки в node.js?

Ниже приведен пример того, что я вижу, но использует/dev/random для медленного генерации данных (если ваша система не делает много). То, что я нахожу, это то, что процесс завершится, как только устройство генерирует данные после поток был закрыт.

var util = require('util'), 
    PassThrough = require('stream').PassThrough, 
    fs = require('fs'); 

// If the system is not doing enough to fill the entropy pool 
// /dev/random will not return much data. Feed the entropy pool with : 
// ssh <host> 'cat /dev/urandom' > /dev/urandom 
var readStream = fs.createReadStream('/dev/random'); 
var pt = new PassThrough(); 

pt.on('data', function (data) { 
    console.log(data) 
    console.log('closing'); 
    readStream.close(); //expect the process to terminate immediately 
}); 

readStream.pipe(pt); 

Update: 1

Я вернулся на этот вопрос и есть еще один образец, это один раз использует и PTY легко воспроизводится в РЕПЛ узле. Войдите в систему на 2 терминалах и используйте pty терминала, в котором вы не используете узел, в следующем вызове createReadStream.

var fs = require('fs'); 
var rs = fs.createReadStream('/dev/pts/1'); // a pty that is allocated in another terminal by my user 
//wait just a second, don't copy and paste everything at once 
process.exit(0); 

В этот момент узел будет просто висеть и не выходить. Это на 10.28.

+0

Возможно, это поможет? http://stackoverflow.com/questions/16399476/readstream-pipe-does-not-close –

+0

Я предполагаю, что это не помогло? В случае, если вы это пропустили, ОП этого вопроса поставил свое решение в нижней части вопроса (для меня, по крайней мере, сначала не было очевидным, что это было не просто больше вопросов внизу). –

+0

Это странное поведение. Код OP немедленно выходит в Mac OS (узел v0.10.21) ... –

ответ

-1

Вы закрываете поток /dev/random, но у вас все еще есть слушатель для события 'data' на проходе, который будет поддерживать приложение до тех пор, пока проход не будет закрыт.

Я предполагаю, что из потока чтения есть некоторые буферизованные данные, и до тех пор, пока это не будет сброшено, сквозной проход не будет закрыт. Но это всего лишь предположение.

Чтобы получить желаемое поведение, вы можете удалить слушатель события на проходной, как это:

pt.on('data', function (data) { 
    console.log(data) 
    console.log('closing'); 

    pt.removeAllListeners('data'); 
    readStream.close(); 
}); 
+0

Нет, процесс все еще просто сидит там после закрытия печати. – ShaneH

+0

какая версия узла и на какой платформе вы работаете? Я пробовал свой код с 0.10.16 в Windows 7, и я получил описанное поведение с вашим кодом и удалив прослушиватель на 'pt' исправил его.У меня нет '/ dev/random', я читал из достаточно большого файла, что чтение было сделано в 64k кусках. Процесс вернулся после прочтения первого фрагмента с моими изменениями, он ждал второго фрагмента с исходным кодом. – mamapitufo

+0

Я запускаю 10.21 на платформе linux. Я ожидаю, что ваш тест будет работать, потому что ваш поток будет постоянно иметь данные/dev/random. Можно открыть/dev/random, к которому он прикреплен («данные»), и он будет сидеть там, пока не будут отправлены какие-то данные. Ваш большой файл отправляет первый фрагмент, вы получаете событие данных, а затем удаляете свои слушатели и закрываете поток, но у потока все еще есть данные. – ShaneH

1

Вместо использование

readStream.close(), 

попробуйте использовать

readStream.pause(). 

Но , если вы используете новейшую версию узла, оберните поток чтения с помощью объекта, созданного с stream модуль по Айзекс, как это:

var Readable = require('stream').Readable; 
var myReader = new Readable().wrap(readStream); 

и использовать MyReader вместо ReadStream после этого.

Удачи! Скажите, если это сработает.

+0

Ну, я получаю красивую трассировку стека, когда я это делаю. :) _stream_readable.js: 730 throw new Error ('Невозможно переключиться в старый режим сейчас.'); – ShaneH

+0

Это связано с [этой проблемой] (https://github.com/isaacs/readable-stream/issues/16), которая была исправлена ​​в [этой фиксации] (https://github.com/isaacs/readable- поток/фиксации/8595376912748ca7984df9047a4a7498fc61f720). –

+0

Я изменил ответ в соответствии с вашей ошибкой. На самом деле мой ответ имел отношение только к версиям старого узла. Простите за это. – sam100rav

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