Записывает больше данных в файл, чем читает?

В настоящее время я экспериментирую с тем, как Python 3 обрабатывает байты при чтении и записи данных, и я столкнулся с особенно тревожной проблемой, которую я не могу найти источник. Я в основном читаю байты из файла JPEG, преобразуя их в целое число, используя ord()затем возвращая байты к их исходному символу, используя строку chr(character).encode('utf-8') и записать его обратно в файл JPEG. Нет проблем, верно? Хорошо, когда я пытаюсь открыть файл JPEG, я получаю уведомление Windows 8.1 о том, что он не может открыть фотографию. Когда я проверяю два файла друг против друга, один составляет 5,04 МБ, а другой - 7,63 МБ, что меня очень смущает.

def __main__():
    operating_file = open('photo.jpg', 'rb')

    while True:
        data_chunk = operating_file.read(64*1024)
        if len(data_chunk) == 0:
            print('COMPLETE')
            break
        else:
            new_operation = open('newFile.txt', 'ab')
            for character in list(data_chunk):
                new_operation.write(chr(character).encode('utf-8'))


if __name__ == '__main__':
    __main__()

Это точный код, который я использую, какие-либо идеи о том, что происходит, и как я могу это исправить?

ПРИМЕЧАНИЕ: я предполагаю, что список номеров, которые list(data_chunk) обеспечивает эквивалент ord(),

2 ответа

Решение

Вот простой пример, с которым вы можете поиграть:

import sys

f = open('gash.txt', 'rb')
stuff=f.read()    # stuff refers to a bytes object
f.close()

print(stuff)

f2 = open('gash2.txt', 'wb')

for i in stuff:
    f2.write(i.to_bytes(1, sys.byteorder))

f2.close()

Как видите, объект bytes является итеративным, но в for петля мы вернемся int в i, Чтобы преобразовать это в байт, я использую int.to_bytes() метод.

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

Для конкретного примера, обратитесь к странице WikiPedia и рассмотрите шестнадцатеричное значение 0xA2,

Это одно двоичное значение, меньше 255, но при кодировании в UTF8 оно становится 0xC2, 0xA2,

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

Если вы пытаетесь понять, как работает файловый ввод / вывод, будьте осторожны с encode() при использовании режима двоичного файла. Двоичные файлы не нужно кодировать и / или декодировать - они являются необработанными данными.

Другие вопросы по тегам