Разница между бинарным и текстовым вводом / выводом в python в Windows - PullRequest
19 голосов
/ 15 июля 2010

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

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

Ответы [ 4 ]

24 голосов
/ 16 июля 2010

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

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

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

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

Однако возникла проблема - не все файлы являются текстовыми, существуют другие форматы иони очень чувствительны к замене одного персонажа другим.Таким образом, они, однако, назовут эти «двоичные файлы» и укажут это на fopen(), включив в режим 'b' - и это пометит библиотеку не делать никакого закулисного преобразования.И вот как это получилось:)

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

20 голосов
/ 15 июля 2010

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

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

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

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

1 голос
/ 15 июля 2010

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

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

0 голосов
/ 15 июля 2010

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

...