2015-02-23 4 views
2

В попытке создать простой cat клон в питона,Как узнать, когда stdin пуст, если он содержит EOF?

sys.stdout.write(sys.stdin.read()) 

Я заметил, что это не удается ужасно для бинарных файлов (т.е. python cat.py <binaryfile> supposed_copy), содержащих CTRL + ZEOF/substitude character 0x1a, так что, кажется, вызывает read(), чтобы рассмотреть его проделанную работу. Я не могу просто перекосить код навсегда, чтобы обойти это, так как очевидно, что в какой-то момент stdin.read() будет ждать ввода нового ввода, который после достижения истинного конца ввода никогда не произойдет.

Итак, как это можно исправить, т.е.

  • Как узнать, когда файл перенаправлен stdin полностью читать, или
  • , как правильно обращаться с этим?
+0

Похоже, вы открываете файл как текст вместо двоичного файла. Можете ли вы показать заявление 'open', пожалуйста? – cdarke

+0

@cdarke: Python открывает stdin и stdout для вас ... –

+1

Это, вероятно, дает вам ответ: http://stackoverflow.com/questions/2850893/reading-binary-data-from-stdin –

ответ

2

Расширяя this answer:

if sys.platform == "win32": 
    import msvcrt 
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) 
    msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) 
+0

Ну, это немного проще, чем я ожидал. :) OTOH, я думаю, есть большой спрос на подобные вещи, поэтому имеет смысл, что Microsoft сделала это довольно легко. –

+0

@ PM2Ring Действительно, хотя я удивляюсь, почему Microsoft сделала это различие для начала. Просто автоматическое преобразование CR/LF позволяет мне проклинать много ... –

+0

Ну, Билл Гейтс хотел сделать MS-DOS отличным от Unix. И я думаю, он думал, что CRLF и Ctrl-Z были хорошей идеей в то время. Аналогичные замечания относятся к использованию обратной косой черты в качестве разделителя путей. Но обсуждение этих тем может привести к [Религиозным войнам] (http://forums.xkcd.com/viewforum.php?f=40), поэтому, я думаю, мне лучше заткнуться. :) –

2

Вам нужно будет указать Python на открытие stdin и stdout в двоичном режиме. Вы можете сделать это с помощью опции -u. Например

python -u cat.py <binaryfile> supposed_copy 

Обратите внимание, что это сделает stdin и stdout небуферизован.

+0

Это отлично работает, может ли эффект '-u' быть достигнут из кода Python? –

+1

@TobiasKienzler: Вероятно, нет, поскольку эти файлы уже открыты, когда они передаются в ваш скрипт. Там _might_ будет какая-то магия Windows, которая может изменить режим потока, который уже открыт, но если это так, доступ к нему из Python потребует использования чего-то типа 'ctypes' (который позволяет вызывать функции в библиотеках DLL).Но в любом случае, stdin и stdout являются специальными и обычно связаны с терминалом, поэтому даже если ваша ОС позволяет вам изменять режимы обычных файлов, это может быть трогательно в отношении stdin & stdout. :) (FWIW, я мало что знаю о Windows). –

+0

Какая-то магия Windows: http://stackoverflow.com/a/28673339/321973 Так много для прозрачной переносимости:/ –

1

См. Reading binary data from stdin для объяснения того, как убедиться, что stdin/stdout открыты как двоичные.

+0

Спасибо, действительно [один ответ там] (http://stackoverflow.com/a/4160894/321973) решает это, хотя это не помешает упомянуть, что здесь;) Во всяком случае, я нашел [аналогичный ответ] (http://stackoverflow.com/a/28673339/321973) –

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