文件读写
文件读写
读写文件是最常见的
读文件
在
- 打开文件
- 读取内容
- 关闭文件
一般使用形式如下:
try:
f = open('/path/to/file', 'r') # 打开文件
data = f.read() # 读取文件内容
finally:
if f:
f.close() # 确保文件被关闭
注意到,我们在代码中加了 try...finally
,这是因为,如果打开和读取文件时出现错误,文件就没有被关闭。为了确保在任何情况下,文件都能被关闭,我们加了 try...finally
。
上面的代码中open
函数的常用模式主要有:
‘r’ | 读模式 |
---|---|
‘w' | 写模式 |
‘a' | 追加模式 |
‘b' | 二进制模式(可添加到其他模式中使用) |
‘+' | 读 |
上面的读文件做法很繁琐,我们可以使用with
语句来帮我们自动调用 close
方法:
with open('/path/to/file', 'r') as f:
data = f.read()
可以看到,这种方式很简洁,而且还能在出现异常的情况下自动关闭文件。
通常而言,读取文件有以下几种方式:
- 一次性读取所有内容,使用
read()
或readlines()
; - 按字节读取,使用
read(size)
; - 按行读取,使用
readline()
;
读取所有内容
读取所有内容可以使用
10 1 9 9
6 3 2 8
20 10 3 23
1 4 1 10
10 8 6 3
10 2 1 6
我们使用 readlines()
将文件读入一个字符串列表:
with open('data.txt', 'r') as f:
lines = f.readlines()
line_num = len(lines)
print lines
print line_num
执行结果:
['10\t1\t9\t9\n', '6\t3\t2\t8\n', '20\t10\t3\t23\n', '1\t4\t1\t10\n', '10\t8\t6\t3\n', '10\t2\t1\t6']
6
可以看到,列表中的每个元素都是一个字符串,刚好对应文件中的每一行。
按字节读取
如果文件较小,一次性读取所有内容确实比较方便。但是,如果文件很大,比如有
with open('path/to/file', 'r') as f:
while True:
piece = f.read(1024) # 每次读取 1024 个字节(即 1 KB)的内容
if not piece:
break
print piece
在上面,我们使用 f.read(1024)
来每次读取
def read_in_chunks(file_object, chunk_size=1024):
"""Lazy function (generator) to read a file piece by piece.
Default chunk size: 1k."""
while True:
data = file_object.read(chunk_size)
if not data:
break
yield data
with open('path/to/file', 'r') as f:
for piece in read_in_chunks(f):
print piece
逐行读取
在某些情况下,我们希望逐行读取文件,这时可以使用 readline()
方法。
看看例子:
with open('data.txt', 'r') as f:
while True:
line = f.readline() # 逐行读取
if not line:
break
print line, # 这里加了 ',' 是为了避免 print 自动换行
执行结果:
10 1 9 9
6 3 2 8
20 10 3 23
1 4 1 10
10 8 6 3
10 2 1 6
文件迭代器
在readline()
是一样的,而且更简洁。
看看例子:
with open('data.txt', 'r') as f:
for line in f:
print line,
在上面的代码中,for line in f
,它是逐行迭代的。
看看执行结果:
10 1 9 9
6 3 2 8
20 10 3 23
1 4 1 10
10 8 6 3
10 2 1 6
再看一个例子:
with open(file_path, 'r') as f:
lines = list(f)
print lines
执行结果:
['10\t1\t9\t9\n', '6\t3\t2\t8\n', '20\t10\t3\t23\n', '1\t4\t1\t10\n', '10\t8\t6\t3\n', '10\t2\t1\t6']
可以看到,我们可以对文件迭代器执行和普通迭代器相同的操作,比如上面使用 list(open(filename))
将readlines
是一样的。
写文件
写文件使用 write
方法,如下:
with open('/Users/ethan/data2.txt', 'w') as f:
f.write('one\n')
f.write('two')
- 如果上述文件已存在,则会清空原内容并覆盖掉;
- 如果上述路径是正确的(比如存在
/Users/ethan 的路径) ,但是文件不存在(data2.txt 不存在) ,则会新建一个文件,并写入上述内容; - 如果上述路径是不正确的(比如将路径写成
/Users/eth ) ,这时会抛出IOError ;
如果我们想往已存在的文件追加内容,可以使用 ‘a’ 模式,如下:
with open('/Users/ethan/data2.txt', 'a') as f:
f.write('three\n')
f.write('four')