本节将介绍与文件相关的python操作,主要为txt文件。文末的实例将给出一个gbk编码的文件转换成utf-8编码的文件。
一,基本操作
在python3的环境下,文件操作非常的简单,python会自动导入io库,不需要手动去指定。
首先创建一个测试文件testFile.txt,内容为下图。
- open()
当我们需要打开一个文件,或者创建一个文件的时候,可以使用open函数。该函数可以接收三个常用的参数,分别是:文件路径,打开方式,编码格式。可以只给定一个路径。
打开方式有以下几个选项:
以测试文件为例,读取测试文件。
默认读取文件:
以二进制形式读取文件:
- read()
上文我们使用到了read()函数,可以通过这个函数来读取文本的内容,同时也可以赋予参数来指定,我们想要读取的字节。
注意转义符’\n’为1个字符。
- close()
可以使用close()函数来手动关闭文件,如果你写入过该文件,那么务必要去关闭该文件,因为python会将你写入的一部分数据暂时的存放在缓存区(为了效率),如果因为某些原因程序停止了,那么这些程序将无法写入到文件之中。所以,尽可能的要使用close()方法。
你可以使用:
# 在这里打开文件
try:
# 将数据写入到文件中
finally:
file.close()
这样能捕获异常之后,正常关闭文件。
另外还有另一种方式可用。
with open(filePath) as f:
return f.read()#返回文件内容
你可以在with语句体内编写你要执行的操作,执行完之后,会自行关闭文件。
- write()
可以使用write(),向文件中写入一些内容。
因为笔者是在windows环境下做的测试,所以需要使用gbk编码打开文件,写入的中文才会是正确的,如果以utf-8编码打开,写入则会是乱码。
with open("C:\\Users\\ForPython3\\Desktop\\testFile.txt","a+",encoding="gbk") as f:
f.write('\n我是AngryCaveman')
- readline()
顾名思义,逐行读取。
- redalines()
将文件中的所有行都读取出来,在文件内容较多时,这种方式将占有大量的内存,下一节将会提到一个更好的办法。
二,文件迭代
通过一个简单的例子我们来学习一下文件迭代。
问题:逐行打印testFile.txt的文件内容。
我们可以使用while True语句输出文件所有的内容,当读取的行为空时跳出循环。
with open("C:\\Users\\ForPython3\\Desktop\\testFile.txt") as f:
while True:
line=f.readline()
if not line:break
print(line)
可是,事实是我们应该尽可能的使用for循环,这样就需要一次把所有行都读出来。
with open("C:\\Users\\ForPython3\\Desktop\\testFile.txt") as f:
for line in f.readlines():
print(line)
在上述的代码中,都使用到了with语句体,实际上,如果你只是读取文件,并不往里面写入内容的话,可以不使用with,也无需close()。
for line in open("C:\\Users\\ForPython3\\Desktop\\testFile.txt"):
print(line)
就像在上文中提到的那样,当文件最够大的时候,f.readlines()这样会占有很多的内存。于是python提供一个新的模块fileinput,能够实现延迟行迭代,你只需要提供一个文件名给他。
import fileinput
for line in fileinput.input("C:\\Users\\ForPython3\\Desktop\\testFile.txt"):
print(line)
三,实例
在实际进行文件操作时,遇到一个问题,使用sax解析xml文件,文件为gbk编码,导致解析失败,另外将gbk转码为utf-8之后,由于\t\n等转义符的存在,还会导致解析数据为空,所以此处需要两个操作,gbk转utf-8,正则表达式去除转义符。
src为原文件路径,dst为处理后结果文件路径。
import os
import re
def ReadFile(filePath):
with open(filePath,"r",encoding="gbk") as f:
return f.read()
def WriteFile(filePath,u):
with open(filePath,"w",encoding="utf-8") as f:
u=u.replace("GB2312","UTF-8")
pattern1 = re.compile('>\\s+')
u=re.sub(pattern1, '>', u)
f.write(u)
def GBK_2_UTF8(src,dst):
content = ReadFile(src)
WriteFile(dst,content)