Из Википедии ( выделенная мина ):
Ввод с терминала никогда не «заканчивается» (если устройство не отключено) , но полезно ввести более одного «файла» в терминал, поэтому последовательность клавиш зарезервировано для указания конца ввода. В UNIX перевод нажатия клавиши в EOF выполняется драйвером терминала , поэтому программе не нужно отличать терминалы от других входных файлов.
Нет способа отправить символ EOF
, как вы ожидаете. EOF
на самом деле не персонаж, который существует. Когда вы находитесь в терминале, вы можете нажать последовательность клавиш ctrl z в Windows и ctrl d в UNIX-подобной окружающие среды. Они генерируют управляющие символы для терминала (код 26 в Windows, код 04 в UNIX) и считываются терминалом. После этого терминал (после чтения этого кода) по существу прекратит запись в программы stdin
и закроет it.
В Python файловый объект будет .read()
навсегда. Условие EOF состоит в том, что .read()
возвращает ''
. В некоторых других языках это может быть -1
или другое условие.
Рассмотрим:
>>> my_file = open("file.txt", "r")
>>> my_file.read()
'This is a test file'
>>> my_file.read()
''
Последний символ здесь не EOF
, там просто ничего нет. Python имеет .read()
до конца файла и не может .read()
больше.
Потому что stdin
в специальном типе «file» не имеет конца. Вы должны определить этот конец. Терминал определил этот конец как управляющие символы, но здесь вы не передаете данные в stdin
через терминал, вам придется управлять им самостоятельно.
Просто закрыв файл
Вход [...] никогда не «заканчивается» (если устройство не отключено)
Закрытие stdin
, пожалуй, самое простое решение здесь. stdin
- это бесконечный файл, поэтому, как только вы закончите запись в него, просто закройте его.
Ожидайте свой собственный управляющий персонаж
Другой вариант - определить свой собственный управляющий персонаж. Вы можете использовать все, что вы хотите здесь. В приведенном ниже примере используется байт NULL.
питон
class FileWithEOF:
def __init__(self, file_obj):
self.file = file_obj
self.value = bytes()
def __enter__(self):
return self
def __exit__(self, *args, **kwargs):
pass
def read(self):
while True:
val = self.file.buffer.read(1)
if val == b"\x00":
break
self.value += val
return self.value
data = FileWithEOF(sys.stdin).read()
Узел
childProcess = require('child_process').spawn('./python_code.py');
childProcess.stdin.write("Some text I want to send.");
childProcess.stdin.write(Buffer.from([00]));
Возможно, вы читаете неправильную длину
Я думаю, что значение, которое вы захватываете в Len
, меньше длины вашего файла.
питон
import sys
while True:
length = int(sys.stdin.read(2))
with open("test.txt", "a") as f:
f.write(sys.stdin.read(length))
Узел
childProcess = require('child_process').spawn('./test.py');
// Python reads the first 2 characters (`.read(2)`)
childProcess.stdin.write("10");
// Python reads 9 characters, but does nothing because it's
// expecting 10. `stdin` is still capable of producing bytes from
// Pythons point of view.
childProcess.stdin.write("123456789");
// Writing the final byte hits 10 characters, and the contents
// are written to `test.txt`.
childProcess.stdin.write("A");