Чтение двоичного файла в режиме чтения Python 3 - проходит в Windows, происходит сбой в Linux - PullRequest
1 голос
/ 05 апреля 2019

Я выполняю этот кусок кода против

Python в Windows

'3.6.8 |Anaconda, Inc.| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]'

и

Python в Linux

'3.6.6 (default, Mar 29 2019, 00:03:27) \n[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]'

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

import os
import tempfile
temp_dir = tempfile.mkdtemp()
temp_file = os.path.join(temp_dir, 'write_file')

expected_bytes = bytearray([123, 3, 255, 0, 100])
with open(temp_file, 'wb') as fh:
    fh.write(expected_bytes)

with open(temp_file, 'r', newline='') as fh:
    actual = fh.read()

Исключение в Linux:

Traceback (most recent call last):
  File "<input>", line 11, in <module>
  File "/home/.../lib64/python3.6/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 2: invalid start byte

Отображение кодировки системы по умолчанию (с sys.getdefaultencoding()) показывает 'utf-8' на обеих машинах.

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Если вы записали файл в байтах, вы должны прочитать его в байтах.

f = open("myfile.txt", "rb")

Если вы читаете его как текст (используя "r" или "rt"), тогда будет предпринята попытка декодировать его в Unicode. Какая кодировка используется по умолчанию, зависит от платформы. Но вы явно не хотите, чтобы он декодировался вообще.

1 голос
/ 05 апреля 2019

При открытии файла в текстовом режиме, поэтому при 'rt' (где по умолчанию используются и r, и t), все, что вы читаете из файла, прозрачно декодируется на лету и возвращается как str объекты, как описано в Текстовый ввод / вывод .

Вы можете принудительно использовать кодировку при открытии файла, например:

f = open("myfile.txt", "r", encoding="utf-8")

Как объяснено в документации для open :

Кодировка по умолчанию зависит от платформы (независимо от того, что возвращает locale.getpreferredencoding ()), но может использоваться любая кодировка текста, поддерживаемая Python.Список поддерживаемых кодировок см. В модуле кодеков.

(обратите внимание, что sys.getdefaultencoding() является чем-то не связанным: он возвращает имя текущей строковой кодировки по умолчанию, используемой реализацией Unicode)

Как вы указали в комментариях, в вашей системе locale.getpreferredencoding() выдает 'cp1252' в Windows и 'UTF-8' в Linux.

CP-1252 - это один байткодировка, в которой каждый байт соответствует символу.Итак, какой бы файл вы ни читали, содержащиеся в нем данные можно превратить в строку.

UTF-8 , однако, использует кодировку переменной ширины, в которой не все последовательности байтов являются действительнымии представлять персонажа.Вот почему попытка прочитать ваш файл в вашей системе Linux не удалась, если не удалось расшифровать какой-либо байт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...