您的位置:首页 > 编程语言 > Python开发

Python 文件 IO

2017-10-11 17:59 127 查看

简述

文件是磁盘上的一个指定位置,用来存储相关信息。它用于永久地将数据存储在非易失性的内存中(例如:硬盘)。

在 Windows 中,文件可以是文本文档、图片、程序等,且通常会有相应的扩展名(例如:
.txt
)。而在 Linux 中,一切皆文件。

对于 Python 而言,文件是一种类型对象,像前面介绍的其他类型(例如:
str
)一样。

简述

三部曲

打开模式

打开文件
指定打开模式

指定编码类型

关闭文件
常规方式

异常处理

使用 with 语句

文件写入

文件读取
readsize

readlinesize

readlinessize

文件的方法

版权所有:一去丶二三里,转载请注明出处:http://blog.csdn.net/liang19890820

三部曲

在 Python 中,文件操作按照以下顺序进行:

打开文件(open)

执行读取/写入操作(read/write)

关闭文件(close)

在读写文件时,首先要打开它。在操作完成后,需要对文件进行关闭,以便释放与文件绑定的资源。

打开模式

在打开文件时,可以指定打开模式(
mode
):

模式描述
'r'
以读方式打开文件,可读取文件信息(默认)
'w'
以写方式打开文件,可向文件写入信息(清空该文件,再写入新内容)。若文件不存在,则创建。
'x'
打开独占创建,如果文件已经存在,则失败。
'a'
以追加方式打开文件(写入的数据会被加到文件末尾,即:文件原先的内容会被保留)。若文件不存在,则创建。
'b'
二进制模式
't'
文本模式(默认)
'+'
打开一个用于更新(读取和写入)的文件
默认模式是
'r'
,以只读方式打开文件,用于读取文本(相当于
'rt'
)。对于二进制读写访问,模式
'w+b'
打开并将文件截断为 0 字节(清空文件),
'r+b'
打开文件而不截断。

可以看出,Python 区分了二进制和文本 I/O:

以二进制模式打开文件(
mode
中包含
'b'
),内容将作为
bytes
对象返回,无需任何解码。

以文本模式打开文件(默认值,或
mode
中包含
't'
),内容将作为
str
返回。首先使用平台相关编码对字节进行了解码,如果给出,则使用指定的编码。

打开文件

内置函数
open()
用于打开文件,并返回一个文件对象(也称为:句柄):

>>> f = open("test.txt")  # 打开当前目录中的文件
>>> f = open("/home/wang/workspace/python/test.txt")  # 指定完整路径


指定打开模式

如果不指定模式,那么默认为
'r'
,以只读方式打开文件:

>>> f = open("test.txt")  # 相当于 'r' 或 'rt'
>>> f.mode
'r'


此外,还可以显式指定打开模式 - 读取使用
'r'
、写入使用
'w'
、追加使用
'a'


>>> f = open("test.txt", 'w')  # 以文本模式写入


还可以指定以文本模式或二进制模式打开文件:

>>> f = open("img.bmp", 'r+b')  # 以二进制模式读写


注意: 二进制模式是处理非文本文件(例如:图像、exe)时使用的模式。

指定编码类型

默认的编码依赖于平台。在 Windows 中:

>>> f = open("E:/test.txt")
>>> f.encoding
'cp936'


在 Linux 中:

>>> f = open("/home/wang/workspace/python/test.txt")
>>> f.encoding
'UTF-8'


可以看到,不同平台上的编码是不一样的。所以如果依赖于默认编码,那么代码在不同平台上将会有不同表现。

因此,当以文本模式处理文件时,强烈建议指定编码类型:

f = open("test.txt", mode = 'r', encoding = 'utf-8')


关闭文件

当完成对文件的操作时,需要适当地关闭,以释放与该文件绑定的资源。

常规方式

使用
close()
方法来完成:

f = open("test.txt", encoding = 'utf-8')
# ... 执行文件操作
f.close()


然而,这种方式并不完全安全,因为在对文件执行某些操作时很有可能会引发
IOError
。一旦出错,代码将会退出而无法关闭文件。

异常处理

更安全的方式是使用
try...finally
块:

try:
f = open("test.txt", encoding = 'utf-8')
# 执行文件操作
finally:
f.close()


这样,即使出现异常,也可以确保文件能够被正确地关闭。

使用 with 语句

每次都要这么写,简直太繁琐了。所以,Python 引入了
with
语句:

with open("test.txt", encoding = 'utf-8') as f:
# 执行文件操作


这可以确保当
with
中的块退出时,文件被安全地关闭,该动作是在内部完成的。

这和
try ... finally
的效果是一样的,而且无需显式地调用
close()
,代码简洁、优雅,更符合 Pythonic 的要求。

文件写入

为了写入文件,需要以写
'w'
模式打开,追加则使用
'a'
或独占创建使用
'x'


注意: 在使用
'w'
模式时需要小心,因为如果文件存在,则会进行覆盖,以前的所有数据都将被清除。

要写入一个字符串或字节序列(对于二进制文件),使用
write()
方法,该方法会返回写入文件的字符数。

>>> with open("poem.txt", 'w', encoding = 'utf-8') as f:
...     f.write("Very quietly I take my leave\n")
...     f.write("As quietly as I came here\n")
...
29
26


注意: 要区分不同的行,需要包含换行符(
\n
)。

可以看到,文件已经被创建了,而且包含了写入的内容:

$ cat poem.txt
Very quietly I take my leave
As quietly as I came here


如果要向文件追加内容,使用模式
'a'


>>> with open("poem.txt", 'a', encoding = 'utf-8') as f:
...     f.write('Gently I flick my sleeves\n')
...     f.write('Not even a wisp of cloud will I bring away\n')
...
26
43


再次打开文件,可以看到之前的内容也会被保留:

$ cat poem.txt
Very quietly I take my leave
As quietly as I came here
Gently I flick my sleeves
Not even a wisp of cloud will I bring away


文件读取

读取和写入一样简单,要读取文件的内容,必须以读
'r'
模式打开文件。

读取方式有多种:

read([size])
: size 为可选参数,如果指定了 size,就按照指定长度从文件中读取内容;否则,就读取全部内容。被读取的内容作为字符串返回,这样做的好处是:内容被存放在内存中,随用随取,方便快捷。但也因为这一点,如果文件过大,内存会吃不消。

readline([size])
:size 含义同上。它以行为单位返回字符串,也就是每次读取一行,依次循环,如果不限定 size,直到最后一个返回的是空字符串,意味着到文件的末尾(EOF - End-of-file)。

readlines([size])
:size 含义同上。返回以行为单位的列表,相当于先执行
readline()
,得到每一行,然后将所有行放入列表中,最后将列表返回。

read([size])

可以使用
read(size)
方法读取数据的大小。如果没有指定 size,将读取并返回到文件的末尾。

>>> with open("poem.txt", 'r', encoding = 'utf-8') as f:
...     f.read(4)  # 读取前 4 个节数
...     f.read(9)  # 读取后续的 9 个节数
...     f.read()  # 读取剩余的内容(直到文件末尾)
...     f.read()  # 进一步读取,返回空字符串
...
'Very'
' quietly '
'I take my leave\nAs quietly as I came here\nGently I flick my sleeves\nNot even a wisp of cloud will I bring away\n'
''


可以看到,
read()
方法将换行作为
\n
返回。一旦到达文件的末尾,在进一步读取时便会返回空字符串。

可以使用
seek()
方法来更改当前的文件的游标(位置)。类似地,
tell()
方法返回当前的位置(以字节数为单位)。

>>> with open("poem.txt", 'r', encoding = 'utf-8') as f:
...     f.read(4)  # 读取前 4 个节数
...     f.tell()  # 获取当前文件位置
...     f.seek(0)  # 将文件游标移到初始位置
...     print(f.read())  # 读取整个文件
...
'Very'
4
0
Very quietly I take my leave
As quietly as I came here
Gently I flick my sleeves
Not even a wisp of cloud will I bring away


readline([size])

另外,可以使用
readline()
方法来读取文件的各个行,该方法会读取文件直到换行符(包括换行符)。

>>> with open("poem.txt", 'r', encoding = 'utf-8') as f:
...     f.readline(4)  # 读取第一行中前 4 个字节
...     f.readline()  # 读取第一行中的剩余内容
...     f.readline()  # 读取第二行
...     f.readline()  # 读取第三行
...     f.readline()  # 读取第四行
...     f.readline()  # 进一步读取,返回空字符串
...
'Very'
' quietly I take my leave\n'
'As quietly as I came here\n'
'Gently I flick my sleeves\n'
'Not even a wisp of cloud will I bring away\n'
''


readlines([size])

最后,
readlines()
方法返回整个文件的剩余行数的列表,所有这些读取方法在到达文件结束时(EOF)返回空值。

指定
size


>>> with open("poem.txt", 'r', encoding = 'utf-8') as f:
...     f.readlines(35)
...
['Very quietly I take my leave\n', 'As quietly as I came here\n']


注意: 返回总和大约为
size
字节的行,而且所返回的必然都是完整的行数据。大多数情况下,实际读取的可能比
size
大,因为需要填充缓冲区。

不指定
size


>>> with open("poem.txt", 'r', encoding = 'utf-8') as f:
...     f.readlines()
...
['Very quietly I take my leave\n', 'As quietly as I came here\n', 'Gently I flick my sleeves\n', 'Not even a wisp of cloud will I bring away\n']


通常情况下,如果文件不太大,则可以很方便地使用这种方式将文件读取到完整的数据结构中。

文件的方法

文件对象提供了许多方法:

>>> f = open("poem.txt")
>>>
>>> type(f)
<class '_io.TextIOWrapper'>
>>>
>>> dir(f)
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writelines']


其中一些在上面已经介绍过了,以下是方法列表的简单说明:

方法描述
close()
关闭一个打开的文件。如果文件已经关闭,则没有效果。
detach()
将底层二进制缓冲区从
TextIOBase
中分离出来并返回
fileno()
返回文件的整数号(文件描述符)
flush()
刷新文件流的写缓冲区
isatty()
如果文件流是交互式的,返回
True
read(n)
从文件中读出最多
n
个字符。如果是负数的或不指定,则读到文件的末尾。
readable()
如果可以读取文件流,则返回
True
readline(n=-1)
从文件读取并返回一行。如果指定,最多读取
n
个字节。
readlines(n=-1)
从文件中读取并返回列表行。如果指定,最多读取 n 个字符。
seek(offset,from=SEEK_SET)
将文件位置更改为
offset
字节,参考
from (start, current, end)
seekable()
如果文件流支持随机访问,则返回
True
tell()
返回当前文件位置
truncate(size=None)
将文件流大小调整为
size
字节。如果未指定
size
,调整大小至当前位置。
writable()
如果文件流可以写入,则返回
True
write(s)
将字符串
s
写入文件,并返回写入的字符数。
writelines(lines)
写入文件列表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息