Python 将更多数据写入文件而不是读取?

Python 将更多数据写入文件而不是读取?,python,python-3.x,read-write,bytestream,Python,Python 3.x,Read Write,Bytestream,我目前正在试验Python3在读取和写入数据时如何处理字节,我遇到了一个特别麻烦的问题,我似乎找不到问题的根源。我基本上是从JPEG文件中读取字节,使用ord()将它们转换为整数,然后使用行chr(character.encode('utf-8')将字节返回到其原始字符,并将其写入JPEG文件。没问题吧?当我尝试打开JPEG文件时,我收到一个Windows8.1通知,说它无法打开照片。当我检查这两个文件时,一个是5.04MB,另一个是7.63MB,这让我非常困惑 def __main__():

我目前正在试验Python3在读取和写入数据时如何处理字节,我遇到了一个特别麻烦的问题,我似乎找不到问题的根源。我基本上是从JPEG文件中读取字节,使用
ord()
将它们转换为整数,然后使用行
chr(character.encode('utf-8')
将字节返回到其原始字符,并将其写入JPEG文件。没问题吧?当我尝试打开JPEG文件时,我收到一个Windows8.1通知,说它无法打开照片。当我检查这两个文件时,一个是5.04MB,另一个是7.63MB,这让我非常困惑

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\u chunk)
提供的数字列表等同于
ord()

这里是一个您可能希望使用的简单示例:

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对象是iterable,但是在
for
循环中,我们在
i
中返回了
int
。要将其转换为字节,我使用
int.To_bytes()
方法。

当您有一个代码点并用UTF-8对其进行编码时,结果可能包含比原始结果更多的字节

对于一个具体的例子,参考并考虑十六进制值<代码> 0xA2 ./P> 这是一个小于255的单二进制值,但当编码为UTF8时,它变为

0xC2,0xA2

鉴于您正在从源文件中提取字节,我的第一个建议是直接将字节传递给目标文件的编写器


如果您试图了解文件I/O的工作原理,请在使用二进制文件模式时小心
encode()
。二进制文件不需要编码和/或解码-它们是原始数据。

为什么要使用
list
?据我所知,
data\u chunk
将是一个字节对象,可以一次在字节上迭代。我还不明白为什么要指定
uff-8
。如果正在读取字节,则不希望将其转换为字符。请在更小的测试文件(不一定是真正的JPEG)上尝试代码,并使用更小的“块大小”,然后比较两个文件的大小和内容。您还可以轻松测试您的假设是否正确。顺便说一句,在Python3中以二进制模式打开文件进行读取的正确方法是
open(filename'r',newline='')
。写入JPEG文件时,将字节编码为UTF-8是错误的。它将获取任何值高于0x7F的字节,并将其编码为多个字节,从而破坏数据。我之所以编码“utf-8”,是因为没有它,我会出现写入错误,@martineau我不会添加换行参数,因为在读取二进制文件时,我使用换行参数时会出现错误。另外,当我尝试使用较小的chunksizes时,新文件的字节数仍然较高。@cdarke:你是对的,我错了,因为必须使用
newline=''
来获得二进制模式。我把二进制模式和通用换行符转换混淆了,通用换行符转换是文本模式的默认值(在二进制模式下自动抑制)。抱歉。OP使用的是Python 3,因此您以二进制模式打开文件的方式是不正确的(即使它可能在某些操作系统上工作)。@martineau:这段代码在Python 3.5上运行良好。它有什么问题?那么你可能不会在一个重要的操作系统上运行它,比如Windows。另一种可能是测试文件只包含ASCII数据。我问这个问题是因为我(错误地)认为
I
应该是
byte
类型,而不是整数,因为
stuff
bytes
对象(一个8位值的不可变数组)。但是,由于Python没有
byte
类型,因此在数组上迭代会生成
int
类型的值,这些值通常是多字节值。感谢您的支持,并允许我从您的回答中学习。@cdarke:我的愿望与您的不一样……您的解释帮助我澄清了一些关于二进制模式和禁用通用换行符之间区别的困惑,这主要源于csv模块希望在Python 2中以二进制模式打开文件的方式,Python 3中的
newline='
模式。