文件基本操作
打开与关闭文件
open(file_path, mode=‘r’) 传入表示文件路径的字符串,会返回一个文件对象。
执行完open语句之后,文件会被打开,那么这个时候就可以执行一些读写的操作
#假设有一个文件test.txt,里面的内容是:Tester is good job
f = open('test.txt','r')
print(f.read())
#运行结果:
Tester is good job
除了接收相对路径之外,open 也可以接收绝对路径
打开模式
上面代码中提到的 ‘r’ 是文件打开的模式,详情请参考以下内容:
模式 | 描述 |
---|---|
r | 以只读方式打开文件,文件指针默认放在文件开头,文件不存在则报错 |
r+ | 打开一个文件用于读写,文件指针默认放在文件开头,文件不存在则报错 |
w | 打开一个文件只用于写入,如果该文件已存在则将其覆盖,如果不存在,创建新文件 |
w+ | 打开一个文件用于读写,如果该文件已存在则将其覆盖,如果不存在,创建新文件 |
a | 打开一个文件用于追加,如果文件已存在,文件指针会放在文件结尾(也就是说新的内容将会被写到已有内容之后),如果不存在,创建新文件进行写入 |
a+ | 打开一个文件用于读写,如果文件已存在,文件指针会放在文件结尾,如果不存在,创建新文件用于读写 |
其他模式:rb rb+ wb wb+ ab ab+
加个b的作用:以二进制的格式打开文件,进行上述操作 。
文件访问编码
open(file_path, mode=‘r’, encoding=None)
如果没有声明输入字符串的编码为UTF-8,那么写入文件的汉字就会变成乱码
f = open('test.txt','w+')
f.write('你好!世界')
f.close()
#运行后文件里的内容为:
������
因此,如果是写入汉字或者是其他的uncoding的字符的话,就要声明encoding=
f = open('test.txt','w+',encoding='UTF-8')
f.write('你好!世界')
f.close()
#运行后文件里的内容为:
你好!世界
除了UTF-8编码之外常用的还有ACSII
open(file_path, mode=‘r’, encoding=None, errors=None)
既上面所说的encoding之后,还可以通过加上 errors= 来选择对编码错误的处理方法,一般使用 ’ignore‘ 来忽略错误
f = open('text.txt', 'w+', encoding='ascii',errors='ignore')
f.write('你好!世界')
f.seek(0)
print(f.read())
#运行后不会报错,但源文件也不会有改动
关闭文件
f.close() 调用给定文件对象的close方法,这里要特别注意,文件打开之后一定要关闭
f = open('test.txt','r')
f.close() #文件关闭之后也就无法在读取文件内容了
print(f.read())
#运行结果:
ValueError: I/O operation on closed file.
读取/写入 文件
以str字符串形式写入,读取出来的是str字符串,以bytes字符串形式写入,读取出来的是bytes字符串
操作 | 方法 |
---|---|
读取指定大小的内容 | f.read() |
读取一行的内容 | f.readline() |
读取多行内容 | f.readlines() |
写入内容 | f.write(data) |
写入多行(需要自己加换行符) | f.writelines(lines) |
立即刷新缓冲 | f.flush() |
获得游标位置 | f.tell() |
调整游标位置 | f.seek(position) |
read()读取指定大小的内容
#假设有一个文件test.txt,里面的内容是:Tester is good job
f = open('test.txt','r')
print(f.read()) #会输出文件里的全部内容
#运行结果:
Tester is good job
print(f.read()) #如果再次读取的话不会有任何输出
#运行结果:
你无法全部读取文件内容两次,不过倒是可以分段读取:
print(f.read(6)) #会读取内容的前6个字符
#运行结果:
Tester
print(f.read()) #如果再次,会读取剩下的所有内容
#运行结果:
is good job
readline()读取一行的内容
#假设有一个文件test.txt,里面的内容是:
#Tester is good job
#This is twice line
#This is 3th line
f = open('test.txt','r')
print(f.readline()) #会输出内容的第一行
#运行结果:
Tester is good job
print(f.readline()) #如果再次读取的话会再输出一行,以此类推
#运行结果:
This is twice line
readlines()读取多行内容
f = open('test.txt','r')
print(f.readlines()) #会读取所有内容,以一个列表的形式显示
#运行结果:
['Tester is good job\n', 'This is twice line\n', 'This is 3th line']
write(data)写入内容
f = open('test.txt','w+')
print(f.write('happy today!'))
#运行结果:
12 #这里输出的是写入字符的长度
print(f.read()) #在写入后立刻读取是不会出现内容的
writelines(lines)写入多组字符
(不会换行需要自己加换行符)和write的区别在于,writelines可以接收序列类型
li = ['First line', 'Second line']
f = open('test.txt','w+')
f.writelines(li)
f.seek(0)
print(f.readlines())
#运行结果:
['First lineSecond line']
flush()立即刷新缓冲
起到一个保存写入内容的作用
f = open('test.txt','w+')
f.write('happy today!')
f.flush() #使用flush后就可以让write的写入生效
f2 = open('test.txt','r') #另外打开这个文件时,即使不close也可以看到最新的内容
print(f2.read())
#运行结果:
happy today!
tell()获得指针位置
如果不知道写入的具体位置,可以用这个方法查看
f = open('test.txt','w+')
f.write('happy today!')
print(f.tell()) #返回指针的索引位置
#运行结果:
12
seek(position)调整指针位置
括号中输入索引,指针会放到指定索引的位置
f = open('test.txt','w+')
f.write('happy today!')
f.seek(0) #将指针调整到开头,以配合read读取内容
print(f.read())
#运行结果:
happy today!
上下文管理器
with as能够让Python自动执行关闭
with open('test.txt','w') as f: #把打开的文件属性储存到对象f中
f.write('with as good job')
# 跳出with语句块的时候自动执行f.close()
f2 = open('test.txt','r')
print(f2.read())
#运行结果:
with as good job
with as也可以同时驾驭多个文件:
with open('test.txt','w') as f1,\
open('abc.txt','w') as f2:
f1.write('with as good job')
f2.write('hahahahaha')
# 跳出with语句快的时候自动执行f.close()
f3 = open('test.txt','r')
print(f3.read())
f4 = open('abc.txt','r')
print(f4.read())
#运行结果:
with as good job
hahahahaha
引申,使用上下文管理器计算函数运行时间,这里时修改了with as里的内置enter和exit函数
from datetime import datetime
class Run:
def __enter__(self): #进入时调用
self.start = datetime.now()
return self.start
def __exit__(self, exc_type, exc_val, exc_tb): #在代码执行完成后调用
self.end = datetime.now()
print('运行时间是:%s'%(self.end-self.start))
r = Run()
with r as a: #此时调用__enter__
for i in range(10000):
type(2)
StringIO和BytesIO
内存假文件,创建在内存里的文件,关闭程序后即删
文本模式: f = io.StringIO()
import io
myio = io.StringIO() #创建StringIO对象
myio.write('Test strings for io')
print(myio.getvalue()) #获取值
myio.close()
#运行结果:
Test strings for io
二进制模式: f = io.BytesIO()
byio = io.BytesIO() #创建BytesIO对象
byio.write(b'Test bytes for io')
print(byio.getvalue()) #获取值
byio.close()
#运行结果:
b'Test bytes for io'