我讨厌回忆,总让人分不清自己到底是谁。
在Python2中,编码问题被人诟病不止,而写入文件与编码存在很大的关联,为此做一个总结。
使用open直接读写
f1 = open('io1.txt','a+')
f1.write('你好')
print r1.read()
f1.close()
运行结果:
ÌġXc
虽然文件写入是正常的,但是读取的时候乱码了,这是因为win系统的原因,如果想要获取正常的文字应该编码一下,print f1.read().decode(‘gbk’)就可以,但是这样很麻烦。
使用codecs读写
f=codecs.open('io2.txt','r','utf-8')
print f.encoding
# 打印文件编码格式
print f.name
# 打印文件名
for x in f.readlines():
print x
# 打印文件内容
f.close()
codecs可以设置编码格式,但是Python3中在open()下就可以直接设置encoding=’utf-8’,唉。
使用fileinput读写
import fileinput
with fileinput.input(files=('spam.txt', 'eggs.txt')) as f:
for line in f:
process(line)
主要属性
fileinput.filename()
返回当前正在处理的文件名(也就是包含了当前正在处理的文本行的文件)
fileinput.fileno()
返回当前文件的总行数。
fileinput.lineno()
返回当前的行数,这个行数是累计的。多个文件的行数会累加起来。
fileinput.filelineno()
返回当前正在处理的文件的当前行数。每次处理完一个文件并开始处理下一个文件时,该值会重置为1,重新开始计数。
fileinput.isfirstline()
当前行是当前文件的第一行时返回True,否则False
fileinput.isstdin()
当前操作对象为sys.stdin时返回True否则False。
fileinput.nextfile()
关闭当前的文件,跳到下一个文件,跳过的行不计数。
fileinput.close()
关闭整个文件链,结束迭代。
读取大文件
常规的open(xx).read(),本质上调用read()会一次性读取文件的全部内容,然后把内容保存在内存中,如果文本过大,则会导致内存溢出。
可以通过如下方法解决
使用Fileinput模块
import fileinput
for line in fileinput.input(['filename']):
do_something(line)
调用 fileinput.input() 会按照顺序读取行,但是在读取之后不会将它们保留在内存中。
使用生成器函数
def read_in_chunks(filePath, chunk_size=1024*1024):
file_object = open(filePath)
while True:
chunk_data = file_object.read(chunk_size)
if not chunk_data:
break
yield chunk_data
if __name__ == "__main__":
filePath = './path/filename.txt'
for chunk in read_in_chunks(filePath):
print(chunk)
使用上下文管理器
with open('filename', 'r', encoding = 'utf-8') as f:
for line in f:
print(line)
with 语句句柄负责打开和关闭文件(包括在内部块中引发异常时),for line in f 将文件对象 f 视为一个可迭代的数据类型,会自动使用 IO 缓存和内存管理,这样就不必担心大文件了。