文件读写

标签: 

该主题包含 0 则回复,有 1 个参与人,并且由  Teddy6 年, 10 月 前 最后更新。

正在检视 1 篇文章 - 1 至 1 (共计 1 篇)
  • 作者
    文章
  • #1322

    Teddy
    参与者

    转载自廖雪峰的官方网站

    读写档是最常见的IO操作。Python内置了读写档的函数,用法和C是相容的。
    读写档前,我们先必须了解一下,在磁片上读写档的功能都是由作业系统提供的,现代作业系统不允许普通的程式直接操作磁片,所以,读写档就是请求作业系统打开一个档物件(通常称为档描述符),然后,通过作业系统提供的介面从这个档物件中读取资料(读档),或者把资料写入这个档物件(写档)。
    读文件
    要以读档的模式打开一个档物件,使用Python内置的open()函数,传入档案名和标示符:
    >>> f = open('/Users/michael/test.txt', 'r')
    标示符’r’表示读,这样,我们就成功地打开了一个档。
    如果档不存在,open()函数就会抛出一个IOError的错误,并且给出错误码和详细的资讯告诉你档不存在:

    >>> f=open('/Users/michael/notfound.txt', 'r')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    FileNotFoundError: [Errno 2] No such file or directory: '/Users/michael/notfound.txt'

    如果档打开成功,接下来,调用read()方法可以一次读取档的全部内容,Python把内容读到记忆体,用一个str物件表示:

    >>> f.read()
    'Hello, world!'

    最后一步是调用close()方法关闭档。档使用完毕后必须关闭,因为档物件会占用作业系统的资源,并且作业系统同一时间能打开的档数量也是有限的:
    >>> f.close()
    由于档读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭档,我们可以使用try … finally来实现:

    try:
        f = open('/path/to/file', 'r')
        print(f.read())
    finally:
        if f:
            f.close()

    但是每次都这么写实在太繁琐,所以,Python引入了with语句来自动帮我们调用close()方法:

    with open('/path/to/file', 'r') as f:
        print(f.read())

    这和前面的try … finally是一样的,但是代码更佳简洁,并且不必调用f.close()方法。
    调用read()会一次性读取档的全部内容,如果档有10G,记忆体就爆了,所以,要保险起见,可以反复调用read(size)方法,每次最多读取size个位元组的内容。另外,调用readline()可以每次读取一行内容,调用readlines()一次读取所有内容并按行返回list。因此,要根据需要决定怎么调用。
    如果档很小,read()一次性读取最方便;如果不能确定档大小,反复调用read(size)比较保险;如果是设定档,调用readlines()最方便:

    for line in f.readlines():
        print(line.strip()) # 把末尾的'\n'删掉
    file-like Object

    像open()函数返回的这种有个read()方法的物件,在Python中统称为file-like Object。除了file外,还可以是记忆体的位元组流,网路流,自订流等等。file-like Object不要求从特定类继承,只要写个read()方法就行。
    StringIO就是在记忆体中创建的file-like Object,常用作临时缓冲。
    二进位档案
    前面讲的默认都是读取文字档,并且是UTF-8编码的文字档。要读取二进位档案,比如图片、视频等等,用’rb’模式打开档即可:

    >>> f = open('/Users/michael/test.jpg', 'rb')
    >>> f.read()
    b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进位表示的位元组

    字元编码
    要读取非UTF-8编码的文字档,需要给open()函数传入encoding参数,例如,读取GBK编码的档:

    >>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')
    >>> f.read()
    '测试'

    遇到有些编码不规范的档,你可能会遇到UnicodeDecodeError,因为在文字档中可能夹杂了一些非法编码的字元。遇到这种情况,open()函数还接收一个errors参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略:
    >>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')
    写文件
    写档和读档是一样的,唯一区别是调用open()函数时,传入识别字’w’或者’wb’表示写文字档或写二进位档案:

    >>> f = open('/Users/michael/test.txt', 'w')
    >>> f.write('Hello, world!')
    >>> f.close()

    你可以反复调用write()来写入档,但是务必要调用f.close()来关闭文件。当我们写档时,作业系统往往不会立刻把资料写入磁片,而是放到记忆体缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,作业系统才保证把没有写入的资料全部写入磁片。忘记调用close()的后果是资料可能只写了一部分到磁片,剩下的丢失了。所以,还是用with语句来得保险:

    with open('/Users/michael/test.txt', 'w') as f:
        f.write('Hello, world!')

    要写入特定编码的文字档,请给open()函数传入encoding参数,将字串自动转换成指定编码。

    小结
    在Python中,档读写是通过open()函数打开的档物件完成的。使用with语句操作档IO是个好习惯。

正在检视 1 篇文章 - 1 至 1 (共计 1 篇)

抱歉,回复主题必需先登入。