目录:
文件的基本操作
CSV文件的读写
制作备份文件代码demo
json和pickle模块
一:文件的基本操作
在程序中处理的数据都是存储在内存中(因为程序本身就是在内存中运行),但是内存是可丢失性存储,要想永久的保留数据需要将数据写入磁盘中,在磁盘中保留的数据都是持久化数据。
Python语言支持对文件的操作有:
open函数:打开文件
read函数:读入文件
writer函数:写入文件
open函数的使用如下:
def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
open函数的参数:
file:表示文件的路径
mode:表示文件的打开方式与格式,如下:
r:表示以只读的方式打开(默认)。不可以写入,文件不存在则报错。文件指针停在开头
w:表示以只覆盖写入的方式打开(文件不存在则会创建文件),不可以读取
x:表示创建一个新的文件并写入
a:以追加方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾,文件不存在则创建
b:以二进制的方式打开文件
t:以文本的模式打开文件(默认)
+:表示文件可以执行
U:通用换行符模式
还可以使用参数组合的方式来对文件进行操作,如下:
rt:表示以只读的文本格式打开文件
rb:表示以只读的二进制打开文件
r+:表示可读可写(文件不存在则报错),如果想要读取文件则要将文件指针手动置零seek(0,0)
w+:表示可读可写(文件不存在则创建文件)如果想要写入文件则要将文件指针手动置零seek(0,0)
wb:表示只允许写入以二进制来保存
encoding:表示文件的编码格式,有utf-8、gb233(默认是以OS平台格式),需要注意的是写入的编码格式要和读取的方式一致,否则会导致乱码错误等。
文件的read:
文件读取需要使用read函数,使用read函数之前要使用open函数将文件打开。
read函数是默认读取文件的所有内容。可以通过设置参数来调整每次读取的大小,代码如下:
# 文件a.txt中内容是“hello,world”
file = open ( 'a.txt' , 'rt' )
a = file.read ( 2 ) # 每次读取2个字节
print ( a )
# 打印结果如下:
he
# 除了使用read函数,还有readline函数用来直接读取一行,readlines函数用来读取多行,以列表形式保存
# 文件b.txt中的内容是3行,分别是:
# hello
# world
# 你好
file = open('b.txt','rt',encoding='gbk')
a = file.readline() # readine函数是读取一行
print ( a )
file.close() # 每次打开文件流后,需要关闭文件流。
# 打印结果如下:
hello
file = open('b.txt','rt',encoding='gbk')
c = file.readlines()
print ( c )
file.close()
# 打印结果如下:
['hello\n', 'world\n', '你好']
文件的写入操作是通过wirte函数来进行的,代码如下:
file = open ( 'a.txt' , 'w' , encoding='utf-8' ) # encoding表示以'utf-8'的编码格式打开这个文件
file.write( '你好,世界' ) # 向文件a.txt中写入字符"你好世界"
# 因为前面是以只写入的方式打开的,所以read函数不可以使用,故看不到文件内容
# 实际a.txt文件内容是 “你好,世界”
还可以使用二进制的方式向文件里面写入数据,代码如下:
file = open ( 'a.txt' , 'wb' , encoding='utf-8' ) # 'wb'以二进制方式写入
file.write( 'hello'.encode( 'utf-8' ) ) # encode方法将字符串转为二进制
# 因为上面file是以写入二进制的方式打开,所以只能将要写入的数据转为二进制在写入
二:CSV文件
CSV文件(Comma-Separated Values)中文叫逗号分隔值或者字符分割值。
CVS文件是以纯文本的形式存储表格数据,它的特点是单元格之间默认使用逗号进行分隔,行之间使用换行进行分隔。
Python中提供了CVS模块来支持CVS文件的读写,如下:
import csv # 导入cvs模块
file = open(r'\test.csv','rt') # 使用open函数以只读文本的方式打开文件流
r = csv.reader(file) # 利用cvs模块的reader方法来读取文件,reader方法是将一个文件已可迭代对象的方式读出
for i in r: # 遍历可迭代对象r
print(i)
file.close() # 关闭文件流
# 打印结果如下:
['id', 'name', 'age']
['00', 'xiaowang', '12']
从上面可以得知,CVS模块中的reader方法是将文件每一行作为一个列表来保存。
利用CVS模块中的writer方法和writerow方法来向文件中写入数据:
import cvs
file = open( r'\test2.cvs', 'w' newline='' )
w = cvs.writer( file ) # 利用cvs的wirter函数将文件流放入w中
w.writerow( ['name','age'] ) # 利用cvs的writerow函数写入数据
file.close()
# 也可以利用cvs.writerows来写入多行数据,多行数据要以可迭代对象方式
w.writerows( ( [ 'id' ,'name', 'age' ], [ '00' ,'xiaowang' , 18 ] ) )
除了将数据写入到文件中以外,Python还支持利用StringIO(字符串数据)和BytesIO(二进制数据)将数据已字符串格式或二进制格式写入到内存中来提高效率。因为内存的IO速度远远高于磁盘,所以可以理解为将内存作为数据缓冲区。
StringIO和BytesIO都在io模块中,代码如下:
from io import StringIO,BytesIO # 从io包中导入了StringIO模块和BytesIO模块
s = StringIO( ) #创建了一个StringIO流对象
s.write( 'hello' ) # 利用write方法将字符串写入到StringIO流对象中(内存中)
print ( s.getvalue( ) ) # 使用getvalue方法获取内存中的数据
# 打印结果如下:
hello
# BytesIO是将数据转为二进制
b = BytesIO( ) # 创建了一个BytesIO对象
b.writer( '你好'.encode( 'utf-8' ) ) # 利用字符串的encode方法将中文转为'utf-8'编码下的二进制,写入到BytesIO对象中
b.getvalue( ) # 获取内存中BytesIO数据
# 打印结果如下:
b'\xe4\xbd\xa0\xe5\xa5\xbd' # 因为前面将“你好”通过encode转为了二进制编码
# 可以利用decode将二进制转为字符串,如下:
b = BytesIO( ) # 创建BytesIO对象
b.writer( '你好'.encode( 'utf-8' ) # 利用encode方法将中文转为二进制
print ( b.getvalue( ).decode( 'utf-8' ) ) # 利用decode方法将二进制转为'utf-8'编码中的字符
# 打印结果如下:
你好
三:制作文件的备份代码(demo)
import os # 导入OS模块
file_path = input('请输入您要拷贝的文件路径:')
if os.path.isfile(file_path): # 判断用户输入的路径是否存在,并且是文件
file = open(file_path, 'rb')# 打开用户输入的文件,以只读二进制方式
names = os.path.splitext(file_path) # 利用splitext将路径以“.”切割
new_name = names[0] + '.bak' + names[1]# 创建一个新的文件,把读取的内容写入到新的文件里
new_file = open(new_name, 'wb')# 读取文件内容
while True:
content = file.read(1024) # 利用read方法每次读取1024B方式直到读完内容
new_file.write(content) # 将要备份的文件内容写到备份文件中
if not content: # 如果读完则退出循环
break
new_file.close() # 关闭新的备份文件
file.close() # 关闭被备份的文件
else:
print('文件不存在')
四:JSON和PICKLE
利用open函数和write函数可以将数据写入到文件中,但是wirte函数只支持字符串写入到文件中,如果想要将Python对象写入到文件中,则需要将对象先序列化后再写入。
(序列化:将一个Python对象(列表,字典等)写入到文件的过程。反序列化:将文件里的数据,加载成为Python对象的过程。)
json模块是将Python对象和json字符串相互转换。(json本质上是字符串)
json模块中dumps和dump方法实现将Python对象序列化。
import json #导入json模块
a = open(r'\demo.txt','w') # 打开文件,以只写入的方式
b = [ 'lisi', 18, 'add:shanghai']
c = json.dumps(b) # 将列表转为字符串,dumps方法就是将Python对象转为json
a.write(c) # 将已经是字符串的数据写入到a文件中
a.close()
# a文件中的内容如下:
["lisi", 18, "add:shanghai"]
# 上面dumps是将Python对象转为json字符串,没有写入的功能,需要再次调入write函数写入
# 而dump函数有写入的功能,如下:
json.dump( b, a ) # dump(要转为json的对象,file)
json模块中load方法,loads方法是将一个字符串转为Python对象,也就是反序列化。
代码如下:
import json #导入json模块
a = '["name","lisi","age","18"]' # 使用''将一个列表变为字符串
b = json.loads(a) # loads方法将一个字符串转为Python对象(反序列化)
print ( 'b变量里面的内容是{},它的类型是{}'.format(b,type(b) ) )
# 打印结果如下:
b变量里面的内容是['name', 'lisi', 'age', '18'],它的类型是<class 'list'>
# 使用load方法将一个字符串转为Python对象
import json #导入json模块
a = open(r'\demo.txt','r') # 将demo文件以文本方式打开
b = json.load(a) # 利用load方法将文件中的字符转为python对象
print(b,type(b))
a.close()
# 打印结果如下:
['lisi', 18, 'add:shanghai'] <class 'list'>
pickle模块:
pickle模块是将Python对象和二进制相互转换,并且也可以将Python对象写入文件中(以二进制的形式),代码如下:
# pickle的序列化dumps,dump(将Python对象转为二进制)
import pickle
file = open( r'\demo.txt' , 'wb' ) # 将demo.txt以二进制的方式写入
l = [ 'laowang' , 'xiaohong' ]
p = pickle.dumps( l ) # 将Python对象转为二进制
file.write( p )
file.close()
# dump方法直接将Python对象转为二进制并且写入文件中
pickle.domp( file, l )
# load,loads方法是反序列化,将之前写入的内容读取出来
file = open( r'\demo.txt' , 'rb' ) # 因为load,loads是将二进制转为字符串,所以open函数打开的时候也要以二进制来打开
n = pickle.load( file )
print ( n )
file.close()
# 打印结果如下:
[ 'laowang' , 'xiaohong' ]
# loads将一个二进制文件转换成为Python对象(反序列化)
file = open( r'\demo.txt' , 'rb' )
a = file.read() # 读取的是二进制
b = pickle.loads( a )
print ( b )
file.close()
# 打印结果如下
[ 'laowang' , 'xiaohong' ]
(json模块和pickle模块的区别是:json模块是将Python对象转为字符串或将字符串转为Python对象。pickle模块将对象转为二进制或将二进制转为Python对象。json一般用于不同平台之间数据的传递而pickle一般用于将数据存储)