我有一个 pytn3 脚本,它将数据读入一个缓冲区
fp = open("filename", 'rb')
data = fp.read(count)
我不完全理解 (即使在阅读文档之后) 什么read()
返回。它似乎是某种可迭代的二进制数据。但它不是一个列表。
令人困惑的是,在脚本的其他地方,列表用于二进制数据。
frames = []
# then later... inside a loop
for ...
data = b''.join(frames)
无论如何...我想遍历read()
以字为单位返回的对象(又名 2 字节块)
目前脚本包含这个 for 循环
for c in data:
# do something
是否有可能改变c
,使得这个循环遍历字(2 字节块)而不是单个字节?
我不能在循环中使用read()
一次读取 2 个字节。
我们可以使用.read(n)
以二进制模式从文件中显式读取(最多)n
字节(就像它从以文本模式打开的文件中读取n
Unicode 代码点一样)。这是一个阻塞调用,只会在文件末尾读取较少的字节。
我们可以使用iter
的两个参数形式来构建一个迭代器,该迭代器反复调用可调用的:
>>> help(iter)
Help on built-in function iter in module builtins:
iter(...)
iter(iterable) -> iterator
iter(callable, sentinel) -> iterator
Get an iterator from an object. In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.
文件末尾的read
将开始返回空结果,而不会引发异常,因此我们可以将其用于哨兵。
把它放在一起,我们得到:
for pair in iter(lambda: fp.read(2), b''):
在循环中,我们将获得表示两个字节数据的bytes
对象。您应该检查文档以了解如何使用这些。
在二进制模式下读取文件时,会返回一个bytes
对象,该对象也是标准的 pytn 内置方法之一。通常,它在代码中的表示形式看起来像字符串的表示形式,只是它的前缀为b" "
-当您尝试打印它时,每个字节可能会显示一个转义,如\x**
,其中**
是 2 字节
currently accepted answer给出了在bytes
对象中创建单个字节的list
的示例:
L = [bytes_obj[i:i+1] for i in range(len(bytes_obj))]
我想这样修改它会为你工作:
L = [bytes_obj[i:i+2] for i in range(0, len(bytes_obj), 2)]
例如:
by = b"\x00\x01\x02\x03\x04\x05\x06"
# The object returned by file.read() is also bytes, like the one above
words = [by[i:i+2] for i in range(0, len(by), 2)]
print(words)
# Output --> [b'\x00\x01', b'\x02\x03', b'\x04\x05', b'\x06']
或者创建一个生成器,如果您的列表可能太大而无法一次有效存储,则以相同的方式生成单词:
def get_words(bytesobject):
for i in range(0, len(bytesobject), 2):
yield bytesobject[i:i+2]
在最简单的字面意义上,这样的东西给你一个两个字节的时间循环。
with open("/etc/pwd", "rb") as f:
w = f.read(2)
while len(w) > 0:
print( w )
w = f.read(2)
至于你从read
得到什么,它是一个bytes
对象,因为你已经指定了 'b' 作为 'open' 的选项
我认为一个更 pytn 的方式来表达它将通过迭代器或生成器。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(47条)