是否可以使用os.open/read/write/close?

时间:2016-07-24 21:11:45

标签: python file

我打算经常从许多不同的文件中读/写一小段信息。以下有些人为的示例显示,使用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

1 个答案:

答案 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_BINARYO_TEXT标记)。

实际上,在您给出的示例中,这只是意味着您必须更改

的实例
"A"

b"A"

请注意,您也可以在最新版本的Python 2中使用b"..."文字语法,尽管它仍然只是Python 2中的字符串文字。在Python 3中它表示不同类型的对象({ {1}}),文件描述符函数仅限于写入和返回类似字节的对象。

但是如果你正在处理“二进制数据”,那就完全没有限制了。如果您正在处理“文本数据”,可能(不足以猜测您的具体信息)。