Различие между двоичным файлом и текстом ввод-вывод в Python в Windows

Я знаю, что должен открыть использование двоичного файла "rb" вместо "r" потому что Windows ведет себя по-другому для двоичных и недвоичных файлов.

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

19
задан Mad Scientist 15 July 2010 в 16:45
поделиться

4 ответа

Этот режим предназначен для преобразования окончаний строк.

При чтении в текстовом режиме собственные окончания строк платформы ( \ r \ n в Windows) преобразуются в окончания строк в стиле Python \ n . При записи в текстовом режиме происходит обратное.

В двоичном режиме такое преобразование не выполняется.

Другие платформы обычно прекрасно обходятся без преобразования, потому что они изначально хранят окончания строк как \ n . (Исключением является Mac OS, которая раньше использовала \ r .) Код, основанный на этом, однако, не переносим.

21
ответ дан 30 November 2019 в 02:56
поделиться

В Windows текстовый режим преобразует новую строку \n в возврат каретки, за которым следует новая строка \r\n.

Если вы читаете текст в двоичном режиме, то проблем не возникает. Если вы читаете двоичные данные в текстовом режиме, они, скорее всего, будут повреждены.

1
ответ дан 30 November 2019 в 02:56
поделиться

Для чтения файлов разницы быть не должно. При записи в текстовые файлы Windows автоматически испортит ваши переносы строк (добавит \r перед \n). Вот почему вы должны использовать "wb".

-2
ответ дан 30 November 2019 в 02:56
поделиться

Ну это по историческим (или, как я люблю говорить, истерическим) причинам. Режимы открытия файлов унаследованы от библиотеки C stdio, и поэтому мы следуем им.

Для Windows нет разницы между текстовыми и двоичными файлами, как и в любом из клонов Unix. Нет, я серьезно! - Есть (были) файловые системы/ОС, в которых текстовый файл - это совершенно другой зверь, чем объектный файл и так далее. В некоторых нужно было заранее указывать максимальную длину строк, использовались записи фиксированного размера... ископаемые со времен 80-колоночных бумажных перфокарт и тому подобного. К счастью, в Unices, Windows и Mac такого нет.

Однако - при прочих равных условиях - Unix, Windows и Mac истерически отличаются тем, какие символы они используют в выходном потоке для обозначения конца строки (или, что то же самое, в качестве разделителя между строками). В Unix используется \x0A (\n). В Windows используется последовательность из двух символов \x0D\x0A (\r\n); в Mac - просто \xOD (\r). Вот несколько подсказок о происхождении использования этих двух символов - ASCII код 10 называется Line Feed (LF) и при передаче на телетайп заставляет его двигаться вниз на одну строку (Y++), не меняя своего горизонтального положения (X). Возврат каретки (CR) - ASCII 13 - с другой стороны, заставит печатающую каретку вернуться в начало строки (X=0) без прокрутки на одну строку вниз. Поэтому при отправке вывода на принтер необходимо было отправить и \r, и \n, чтобы каретка переместилась в начало новой строки. Теперь при наборе текста на клавиатуре терминала операторы, естественно, должны нажимать одну клавишу, а не две для конца строки. На Apple][ такой клавишей была клавиша "Return" (\r).

Во всяком случае, так обстояли дела. Создатели Си были озабочены переносимостью - большая часть Unix была написана на Си, в отличие от прежних времен, когда ОС писались на ассемблере. Поэтому они не хотели иметь дело с причудами каждой платформы в отношении представления текста, поэтому они добавили этот злой хак в свою библиотеку ввода-вывода, в зависимости от платформы, ввод и вывод в файл будет "исправлен" на лету так, что программа будет видеть новые строки праведным, Unix-way - как '\n' - независимо от того, было ли это '\r\n' из Windows или '\r' из Mac. Таким образом, разработчику не нужно было беспокоиться о том, на какой ОС работает программа, она все равно могла читать и записывать текстовые файлы в родном формате.

Однако была проблема - не все файлы являются текстовыми, есть и другие форматы, и в них очень чувствительны к замене одного символа на другой. Поэтому они решили, что мы будем называть такие файлы "бинарными" и указывать это fopen(), включая 'b' в режим - и это будет флажком для библиотеки, чтобы она не делала никакого скрытого преобразования. Вот так все и получилось :)

Итак, если файл открыт с 'b' в двоичном режиме, то никаких преобразований не будет. Если же он был открыт в текстовом режиме, то в зависимости от платформы могут произойти некоторые преобразования символов новой строки (символов) - с точки зрения Unix. Естественно, на платформе Unix нет никакой разницы между чтением/записью в "текстовый" или "бинарный" файл.

25
ответ дан 30 November 2019 в 02:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: