目录
面向对象---第十一章 IO对象序列化
1.IO流(IO stream)
2.open()方法
3.写入方法:write()
4.对象序列化
面向对象---第十一章 IO对象序列化
1.IO流(IO stream)
(1)概述:在本地进行文件存储,形成持久化的读写数据的能力
(2)IO流
- IO流:输入输出流,指一种将数据从读入内存和从内存中输出的技术
- 作用:持久化数据,保证数据不再丢失
(3)流的分类:
- 字节流(b):字节处理,可以操作一切数据,如:音频、图片、可执行文件、字节流操作大数据时,不建议一次性读取
- 字符流(t):字符只操作UTF-8的字符数据,一般不用考虑存储空间不够用的问题(500w字-10MB)
2.open()方法
(1)过程:
(2)缓冲区(buffer)
1)缓冲区是内存的一部分,在内存中预留了一定存储空间,该空间用于缓冲输入或输出
使用缓冲区的必要性:由于内存的I/O速度远远大于外设的I/O速度,同步读写时会造成内存长时间等待,浪费性能;可能会造成数据溢出或淹没
2)缓冲区分类:
- 全缓冲:填满标准I/O缓冲区才会进行实际的传输操作,硬盘的文件默认使用全缓冲
- 行缓冲:当输入输出遇到换行符时就会缓冲
- 无缓冲:用户不提供缓冲,对数据流立即进行读写操作
(3)格式:f = open(filename,mode,encoding)
- open()方法返回值是一个file对象,可以赋值给一个变量(文件句柄)
- filename:文件名,是一个字符串,包含路径
- encoding:编码格式,一般为utf-8
- mode:打开文件方式
(4)b模式
1)概述:二进制模式:一般用于读取图片、视频等二进制文件
PS:b模式是以byte类型读取文件,返回的byte对象不是字符串,必须指定编码格式,输入的类型必须保证为byte类型
例:
s = 'this is a test'
b = bytes(s, encoding='utf-8')
f = open('test.txt', 'wb')
f.write(b)
f.close()
# 打开方式为wb,写入s串会报错
(5)+模式:
- 对于w+模式,在读写之前后会清空原有数据,建议不要使用
- 对于a+模式,永远的只会在文件的尾部写入,有局限性,不建议使用
- 对于r+模式,也就是读写结合模式,配合seek()和tell()方法实现更多操作
(6)文件对象的操作:
- read(size):读取一定大小的数据,然后作为字符串或字节对象返回,size为可选参数,用于指定读数的数据流,size忽略或为负数表示该文件所有内容都将被读取并返回
f = open('test.txt', 'r')
str1 = f.read(7)
print(str1)
f.close()
# 若文件体积较大,可以分多次读取,使用read(512)方法一点点读取
- readline():从文件中读取一行或多行内容,换行为\n,若读到最后一行则返回空串,用于读一行处理一行,不能回头
f = open('test.txt', 'r')
str1 = f.readline()
print(str1)
f.close()
- readlines():将文件所有行,一行一行全部读入到多个列表中,按顺序存储到列表中,返回一个列表
f = open('test.txt', 'r')
str1 = f.readlines()
print(str1)
f.close()
# ['this is a test']
(7)遍历文件
- 实际上可以将文件对象作为一个迭代器使用
f = open('test.txt', 'r')
for i in f:
print(i,end=' ')
f.close()
# this is a test
小结:几种不同的读取文件的方法,若文件容量小使用read()一次性读取较为方便,若不能确定文件大小则可以使用read(size)反复测试,若是配置文件可以使用readlines()较为方便或者for循环遍历
3.写入方法:write()
- 作用:将字符串或字节数据写入文件
- write()多次操作实际是在内存中完成,并不会立即写入磁盘,只有close()后操作同步到磁盘
- 格式:文件对象.write(‘内容’)
(1)tell():返回文件读写指针的位置,从文件开头算起的字节数
(2)seek():移动若干个字符到指定位置,如:seek(x,1)表示从当前位置开始向后移动x个字符。seek(-x,2)从结尾开始向前移动
f = open('test.txt', 'rb+')
f.write(b'123456789')
f.tell()
print(f.seek(2,2))
print(f.seek(3,1))
f.close()
# (x,数字),数字有0,1,2, 0表示从文件开头算起,1表示从文件读写指针的位置来时算起,2表示从文件的结尾算起,默认为0
(3)close():关闭文件对象,处理完一个文件后,关闭文件并释放资源,则关闭若再次尝试读写操作将会抛出异常,若忘记调用close(),则后果可能数据只会写入一部分,剩余数据会丢失。
4.对象序列化
(1)什么是对象的序列化?
对容器等对象这种抽象的概念转化为真正存储的字符或字节数据的过程。
(2)产生的原因:
- 便于存储:序列化的本质就是将文本信息转为二进制数据流,python中运行的数据。如:序列,字符串元组等要是想永久保存,方便以后使用,必须进行序列化。
- 便于传输:当两个进程进行远距离通信时,彼此可以发送各个类型的数据,无论何种类型数据都会以二进制序列进行传输,接收方收到后进行反序列化,转为可以是识别的字符集恢复为对象。
(3)pickle模块
- 作用:通过pickle模块的序列化操作可以将运行的对象信息存储到文件中,永久保存,通过pickle反序列化操作可以从文件中回复对象
-
常用方法:dump dumps load loads
# dumps 序列化为字节数据
import pickle
list1 = [10, 20, 30, 40, 50]
data1 = pickle.dumps(list1)
print(data1)
# b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00]\x94(K\nK\x14K\x1eK(K2e.'
f = open('test2.txt', 'wb')
f.write(data1)
f.close()
# loads 进行反序列化
import pickle
f = open('test2.txt', 'rb')
show = f.read()
show = pickle.loads(show)
print(show)
f.close()
# [10, 20, 30, 40, 50]
例:将字符串序列化存储到test3.txt中,读取后反序列化输出
# dump
import pickle
str1 = ['china', 'world', 'hello', '1234567']
pickle.dump(str1, open('test3.txt', 'wb'))
f = open('test3.txt', 'rb')
print(f.read())
f.close()
# load
str2 = pickle.load(open('test3.txt', 'rb'))
print(str2)
(4)json模块
- 作用:json模块将对象序列号转化为字符数据,方法同上。
PS:json一般用于处理字典类型数据
import json
data1 = {'username': '杨勇', 'age': '17', 'number': '33'}
print(json.dumps(data1))
data2 = json.dumps(data1)
f = open('test4.txt', 'wt')
f.write(data2)
f.close()
# {"username": "\u6768\u52c7", "age": "17", "number": "33"}
# PS:注意文件打开方式为wt,字符形式