Python文件相关操作
打开文件
打开文件,采用open方法,会将文件的句柄返回,如下:
f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘)
在上面的代码中,open()方法进行打开文件等相关操作,open()方法其中第一个参数是要打开的文件的文件路径,第二个参数是对要打开文件要执行的权限,第三个参数是文件采用字符编码。
而open()方法返回的内容叫做文件句柄。我们可以打印返回的文件句柄来看下:
f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) print(f)
执行的结果如下:
<_io.TextIOWrapper name=‘test_file.txt‘ mode=‘r‘ encoding=‘utf-8‘>
此时文件句柄f中,包含被打开文件的相关信息,而我们可以通过一些属性和方法来获取文件的相关信息。
文件名称
获取被打开文件名称: f.name
f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) print(f.name) # test_file.txt
文件指针
在使用python读取文件的时候,需要参照文件指针来进行读取,而下面我们可以来看下关于文件指针的相关操作。
获取文件指针位置
获取文件指针位置可以使用tell()方法,能够获取文件指针位置
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) # 获取文件指针位置 print(f.tell()) # 返回的值就是文件指针所在的位置
需要注意的是,文件指针并不是不变的,随着文件读取,指针的位置也会发生变化。
调整文件指针位置
因为文件的指针会随着文件的读取而发生变化,那么如果需要调整读取位置重新读取,就需要调整文件指针,在python中,如果想要调整文件指针,可以使用seek()方法
代码如下:
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) f.seek(0) # 将文件指针调整到初始0的位置
那么需要注意的是,seek()方法的括号内写的是指针将要被调整的位置,如果没有设置这个参数,那么执行的时候就会报错。
通常情况下,我们是将参数设置为0。
判断文件指针是否可以移动
在python中的某些时候,我们需要判断指针是否可以进行移动,而实现这样的需求需要采用seekable()方法。如果可以移动,返回True,如果不可以移动,返回False
# seekable()方法,判断当前文件指针是否可以移动 print(f.seekable()) # True
判断文件的字符编码
判断文件的字符编码可以采用encoding属性。
print(f.encoding)
查看文件在内存中的编号
查看文件在内存中的编号,可以采用fileno()方法
print(f.fileno())
判断文件是否可读可写
在Python的文件操作中,需要给予文件句柄不同的权限,而我们常用的文件权限有如下:
打开文件的模式有:
- r,只读模式(默认)。
- w,只写模式。【不可读;不存在则创建;存在则删除内容;】
- a,追加模式。【可读; 不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件
- r+,可读写文件。【可读;可写;可追加】
- w+,写读
- a+,同a
"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
- rU
- r+U
"b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
- rb
- wb
- ab
文件权限的设置可以根据不同的需求,来进行不同的设置,但是在判断文件具有什么权限的时候通常我们使用最多的有是否可读是否可写
判断文件是否可读,使用readable()方法,判断文件是否可写,使用writeable()方法。
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) # 判断文件可读可写的权限 print(f.readable()) print(f.writable())
判断文件是否关闭
文件存在打开的环节,那么就要在不需要文件的时候将文件关闭,从而节约性能资源,那么关闭文件在python中使用close()方法,而判断文件是否关闭,使用closed()方法。
f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) print(f.closed)
读取文件
读取文件中的一行
python中,想要读取文件中的一行内容,可以采用readline()方法,如下:
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) # 读取文件中的一行 print(f.readline())
通过readline()方法可以读取文件中的一行内容,当然,如果想要继续读取下一行,可以继续使用readline()方法。
print(f.readline())
那么此时需要注意的是,每读取一行,文件当中的指针就会发生变化,我们可以使用tell()方法来查看文件指针的变化.
print(f.readline()) # 读取一行内容之后,通过tell()方法来查看文件内容的指针。 print(f.tell())
当然,如果想要读取并且全部输出文件中更多的行数,可以通过循环的方式。
文件中的内容如下:
白日依山尽,
黄河入海流。
欲穷千里目,
更上一层楼。
那么循环读取输出四行:
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) # 想要读取输出四行 for line in range(4): print(f.readline())
输出的结果:
白日依山尽,
黄河入海流。
欲穷千里目,
更上一层楼。
此时,通过循环我们已经顺利的将文件中的四行内容全部输出了,但是发现每一行之间都存在一行空行,原因是在每一行的结尾都存在一个\n换行,那么可以通过rstrip()方法将换行去掉,代码如下:
# 可以将上述的循环改为下面的写法 for line in range(4): print(f.readline().rstrip())
那么代码更改之后的输出样式如下:
白日依山尽,
黄河入海流。
欲穷千里目,
更上一层楼。
每一句后面的换行已经被成功的去除。
但是此时还存在一个问题,就是当文件中行数并不清楚时该如何读取并且输出所有的行呢?
读取文件中的所有行
想要读取文件中的所有的行,可以使用readlines()方法。
代码如下:
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) # 读取文件中的所有的行 print(f.readlines())
输出的内容如下:
[‘白日依山尽,\n‘, ‘黄河入海流。\n‘, ‘欲穷千里目,\n‘, ‘更上一层楼。‘]
那么我们发现此时输出的内容类型为一个列表。并且每一个列表元素的最后都包含一个换行\n。
我们如果想要把返回的所有的内容全部读取输出,可以采用如下的方式:
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) for index in (f.readlines()): print(index.rstrip())
输出的结果如下:
白日依山尽,
黄河入海流。
欲穷千里目,
更上一层楼。
那么此时如果我们想要具体输出其中的某行,可以采用如下的写法:
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) for index,line in enumerate(f.readlines()): if index == 2: print(line.rstrip()) else: continue
输出的结果为:
欲穷千里目,
上面代码中的写法已经完美的实现了输出文件所有内容的需求,但是从实际的应用角度来看,上面的写法只适用于被读取文件较小的情况,如果被读取文件较大,那么上面的代码就会导致程序的等待时间较长。
推荐使用的读取文件中所有内容的写法
那么为了解决上述的问题,我们可以将读取文件所有内容的写法换成如下:
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) # 读取文件所有内容 for line in f: print(line.rstrip())
最终的输出结果为:
白日依山尽,
黄河入海流。
欲穷千里目,
更上一层楼。
同样,现在的这种方法也实现了上面实例的最终效果。
那么这两种方法的区别在于什么呢?
第一种方法,读取文件所有的内容采用的是readlines()方法,先来将文件的所有的行所有的内容全部读取后,再来进行其他操作处理,而第二种方式是一行一行的读取。
当我们使用第一种方式读取一个较大文件时就会导致等待时间过长,而第二种方法则不会存在这种问题。
那么如果想要实现只输出内容中具体的某行,可以采用如下类似的写法:
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) # 读取文件中的第二行 count = 0 for line in f: if count == 1 : print(line) count += 1
Tip:读取文件的内容,还可以采用下面的方式
# 打开文件 f = open(‘test_file.txt‘,‘r‘,encoding=‘utf-8‘) print(f.read())
输出的结果:
白日依山尽,
黄河入海流。
欲穷千里目,
更上一层楼。
但是因为这种输出方式输出后的内容不利于操作,所以这种方式并不是很推荐。
文件的写入操作
说完了文件的读取操作,我们在来说下文件的写入操作。
首先,想要向文件中写入内容,需要将open()方法中的权限进行更改,如下:
# 打开文件 -- 将文件的权限改为 w f = open(‘test_write.txt‘,‘w‘,encoding=‘utf-8‘)
test_write.txt 文件此时是一个空白的文本文件
向文件中写入内容可以采用write()方法
# 打开文件 -- 将文件的权限改为 w f = open(‘test_write.txt‘,‘w‘,encoding=‘utf-8‘) # 使用write()方法向文件中写入内容 f.write(‘Hello,YanYan‘)
此时,执行代码后,test_write.txt 文件的内容由空白就会变为Hello,YanYan
但是在写入内容的时候,有一点是需要注意的,当open()方法返回的文件句柄的权限是w的时候,我们在一个python文件中通过代码向文件中写入内容,例如:
# 打开文件 -- 将文件的权限改为 w f = open(‘test_write.txt‘,‘w‘,encoding=‘utf-8‘) # 使用write()方法向文件中写入内容 f.write(‘Hello,YanYan‘) f.write(‘Hello,Good Gril‘)
那么test_write.txt文件中的内容如下:
Hello,YanYanHello,Good Gril
但是一旦另外一个代码同样通过open()方法打开了test_write.txt,并且文件句柄的权限为w,那么在这个代码中写入的内容就会将test_write.txt文件中之间的内容覆盖掉,就是说,test_write.txt之前的内容就会消失,从而被写入新的内容。
如果想要在文件原内容基础之上追加新的内容,需要将权限w改为a即可。
# 打开文件 -- 将文件的权限改为 a f = open(‘test_write.txt‘,‘a‘,encoding=‘utf-8‘) # 使用write()方法向文件中写入内容 f.write(‘YanYan is good Gril‘)
那么这样就不会产生覆盖。
Tip:需要注意的是,当我们将文件句柄的权限设置为w或者a的时候就不能够读取文件,而如果想要既可以读取又可以写入的话,推荐将文件的权限设置为r+ ,读写模式,即可以读取又可以写入,是目前使用频率较高的文件权限
flush()方法
在python中,我们在向文件中写入内容的时候,看似是写入的代码写入一行,文件就增加一行,
其实在系统执行的时候是先将代码中写入的内容存储到缓存区中,当存储到一定数量时在统一的进行存储。而flush的作用就是手动的进行刷新存储
文件关闭
我们在通过python打开了一个文件后,需要通过close()方法关闭,虽然python的垃圾回收机制会将文件自动关闭,但是如果打开的文件过多,或者文件过大, 那么就会严重的影响性能。
所以在使用文件系统的时候要学会及时关闭,但是在开发中还是会出现忘记关闭文件的情况,为了解决这种问题,我们可以使用with方法来实现,具体代码如下:
# 使用with方法打开文件和关闭文件 with open(‘file_text_bak.txt‘,‘w‘,encoding="utf-8") as f: print(f)
在python2.7之后,with方法还支持一次打开多个文件:
with open(‘file_text_bak.txt‘,‘w‘,encoding=‘utf-8‘) as f ,open(‘file_text.txt‘,‘r‘,encoding=‘utf-8‘) as f_old: print(f_old)
Tip:python文档中规定,一行文旦最好不要超过80个字符,而如果我们像上面那样一次打开两个甚至更多的文件会导致一行的字符过长,可以进行如下的更改。
with open(‘file_text_bak.txt‘,‘w‘,encoding=‘utf-8‘) as f , open(‘file_text.txt‘,‘r‘,encoding=‘utf-8‘) as f_old: print(f_old)