我打算经常从许多不同的文件中读/写一小段信息。以下有些人为的示例显示,使用os
操作直接执行文件描述符时所花费的时间大大减少。除了文件对象的便利之外,我是否遗漏了任何不足之处?
import os
import time
N = 10000
PATH = "/tmp/foo.test"
def testOpen():
for i in range(N):
with open(PATH, "wb") as fh:
fh.write("A")
for i in range(N):
with open(PATH, "rb") as fh:
s = fh.read()
def testOsOpen():
for i in range(N):
fd = os.open(PATH, os.O_CREAT | os.O_WRONLY)
try:
os.write(fd, "A")
finally:
os.close(fd)
for i in range(N):
fd = os.open(PATH, os.O_RDONLY)
try:
s = os.read(fd, 1)
finally:
os.close(fd)
if __name__ == "__main__":
for fn in testOpen, testOsOpen:
start = time.time()
fn()
print fn.func_name, "took", time.time() - start
示例运行:
$ python bench.py
testOpen took 1.82302999496
testOsOpen took 0.436559915543
答案 0 :(得分:1)
我会回答,所以这不会永远保持开放; - )
没有什么可说的:正如您已经指出的那样,file
对象更方便。在一些案例中,它也更具功能性;例如,它执行自己的缓冲层来加速面向行的文本操作(如file_object.readline()
)(BTW,这也是它变慢的一个原因。)并且file
对象努力以相同的方式工作跨所有平台。
但如果你不需要/想要那个,那么使用低级&& zippier os
文件描述符函数。后者有很多,并非所有平台都支持所有平台,并非所有平台都支持所有选项。当然,你有责任将自己限制在一部分操作中。您关注的平台交叉中的选项(通常对os
中的所有函数都是如此,而不仅仅是文件描述符函数 - 名称os
强烈暗示它包含的内容可能是操作系统相关的)。
关于Pythons 2和3,差异是由于Python 3在所有平台上的“文本”和“二进制”模式之间的强烈区别。它是一个Unicode世界,如果没有指定预期的编码,file
个对象的“文本模式”就毫无意义。在Python 3中,如果文件以“文本模式”打开,file
对象读取方法返回str
对象(Unicode字符串),如果处于“二进制模式”,则返回bytes
对象”。类似的写方法。
因为os
文件描述符方法没有编码概念,所以它们只能在Python 3中使用类似字节的对象(无论是否在Windows上,文件描述符是以低位打开的 - 级别os.open()
O_BINARY
或O_TEXT
标记)。
实际上,在您给出的示例中,这只是意味着您必须更改
的实例"A"
到
b"A"
请注意,您也可以在最新版本的Python 2中使用b"..."
文字语法,尽管它仍然只是Python 2中的字符串文字。在Python 3中它表示不同类型的对象({ {1}}),文件描述符函数仅限于写入和返回类似字节的对象。
但是如果你正在处理“二进制数据”,那就完全没有限制了。如果您正在处理“文本数据”,可能(不足以猜测您的具体信息)。