Записывает больше данных в файл, чем читает?
В настоящее время я экспериментирую с тем, как 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()
при использовании режима двоичного файла. Двоичные файлы не нужно кодировать и / или декодировать - они являются необработанными данными.