第八章 IO流及其对象序列化

目录

第八章 IO流及其对象序列化

8.1 IO流

8.1.1 什么是IO流

8.1.2 流的分类

8.2 字符流

8.3 字节流

8.4 对象序列化

8.4.1 什么是对象序列化

8.4.2 pickle模块

8.4.3 json模块

第八章 IO流及其对象序列化

8.1 IO流

8.1.1 什么是IO流

IO流 input output stream

主要是计算机的输入和输出的操作

侠义:常见IO流操作是指的是内存和磁盘之间的输入和输出的操作

IO流的操作是一种持久化操作方式,将数据持久化到磁盘上

python如何操作IO流?

open()全局函数

 open(file, mode='r')

file --------- 表示的是打开或者操作文件的文件名称或者文件的路径

mode='r' ------- 指的是打开的模式(默认值r read 默认的是字符流)

   'r'       open for reading (default)
     'w'       open for writing, truncating the file first
     'x'       create a new file and open it for writing
     'a'       open for writing, appending to the end of the file if it exists
 >>> import os.path as p
 >>> p.abspath(".")
 'C:\\Users\\WX'
 >>> open("a.txt")
 <_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'>
 >>> f = open("a.txt")
 >>> f
 <_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'>
 >>> dir(f)
 ['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'write_through', 'writelines']
 >>> f = open("a.txt")
 >>> f.read()
 '哈哈哈哈哈哈哈哈哈哈哈哈哈'
 >>> f.read()
 ''
 >>> f.read()
 ''
 >>> f.close()
8.1.2 流的分类

根据数据流的流动方向(站在内存的角度来讲):输入流 输出流

把数据存储到磁盘上这是输入流还是输出流?------ 输出流

根据数据的类型:字符流 字节流

8.2 字符流

 >>> f = open("a.txt",mode="r")
 >>> f.read()
 '哈哈哈哈哈哈哈哈哈哈哈哈哈'
 >>> f.close()
 >>> f = open("a.txt",mode = "w")
 >>> f.write("嘿嘿嘿嘿嘿嘿嘿嘿嘿")
 9
 >>> f.close()
 >>> f = open("a.txt",mode = "w")
 >>> f.write("呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵")
 18
 >>> f.flush()
 >>> f.close()

一旦关闭了流,下一次写入的内容会覆盖掉上一次的内容

如何做到不覆盖?

 >>> f = open("b.txt",mode = "a")
 >>> f.write("哈哈哈哈哈哈哈哈")
 8
 >>> f.flush()
 >>> f.close()
 >>> f = open("b.txt",mode = "a")
 >>> f.write("呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵")
 18
 >>> f.close()

注意:本质上mode="r" ------ node="rt" t ---- text字符流

 >>> f = open("b.txt",mode = "at")
 >>> f.write("呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵")
 18
 >>> f.close()
 >>> f = open("b.txt",mode = "rt")
 >>> f.read(2)
 '哈哈'
 >>> f.read(4)
 '哈哈哈哈'
 >>> f.read(8)
 '哈哈呵呵呵呵呵呵'
 >>> f.read(12)
 '呵呵呵呵呵呵呵呵呵呵呵呵'
 >>> f.close()

8.3 字节流

b ------- binary mode

视频、图片、音频、可执行的二进制文件都是二进制数据,使用字节流

mode = "rb" ----- 表示的是字节流的操作IO

 >>> f = open("a.jpg","r")
 >>> f.read()
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 UnicodeDecodeError: 'gbk' codec can't decode byte 0xff in position 0: illegal multibyte sequence
 >>> f.close()
 >>> f = open("a.jpg","rb")
 >>> f.read()

注意:字节流操作过大的数据的时候不建议一次性读取

字节可以操作任何数据,但是字符只能操纵字符数据

>>> f.close()
>>> f = open("a.txt","rb")
>>> f.read()
b'\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7\xba\xc7'

字节数据的备份:

>>> f = open("a.jpg","rb")
>>> ff = open("b.jpg","wb")
>>> ff.write(f.read())
891024
>>> f.close()
>>> ff.close()
#需要将D:\重大城科\上课录屏\18_登录注册习题讲解.mp4视频文件被分到桌面上C:\Users\WX\Desktop\18_登录注册习题讲解.mp4
def copy_file(src,dest):
    f = open(src,"rb")
    ff = open(dest,"wb")
    ff.write(f.read())
    f.close()
    ff.close()

copy_file("D:\\重大城科\\上课录屏\\18_登录注册习题讲解.mp4","C:\\Users\\WX\\Desktop\\18_登录注册习题讲解.mp4")
#需要将D:\重大城科\上课录屏\18_登录注册习题讲解.mp4视频文件被分到桌面上C:\Users\WX\Desktop\18_登录注册习题讲解.mp4
def copy_file(src,dest):
    f = open(src,"rb")
    ff = open(dest,"wb")
    # ff.write(f.read())
    #以M为单位去读取  1M = 1024*1024
    while True:
        data = f.read(1024*1024)
        if  data == b"":
            print("读取完成了!!!!")
            break
        else:
            ff.write(data)
    
    f.close()
    ff.close()

copy_file("D:\\重大城科\\上课录屏\\18_登录注册习题讲解.mp4","C:\\Users\\WX\\Desktop\\18_登录注册习题讲解.mp4")

请输入你要备份的文件的数据路径:D:\重大城科\上课录屏\18_登录注册习题讲解.mp4

请输入你要保存备份文件的路径:C:\Users\WX\Desktop\18_登录注册习题讲解.mp4

#需要将D:\重大城科\上课录屏\18_登录注册习题讲解.mp4视频文件被分到桌面上C:\Users\WX\Desktop\18_登录注册习题讲解.mp4
def copy_file():
    src = input("请输入你要备份的文件的数据路径:")
    dest = input("请输入你要保存备份文件的路径:")
    f = open(src,"rb")
    ff = open(dest,"wb")
    # ff.write(f.read())
    #以M为单位去读取  1M = 1024*1024
    while True:
        data = f.read(1024*1024)
        if  data == b"":
            print("读取完成了!!!!")
            break
        else:
            ff.write(data)
    
    f.close()
    ff.close()

# copy_file("D:\\重大城科\\上课录屏\\18_登录注册习题讲解.mp4","C:\\Users\\WX\\Desktop\\18_登录注册习题讲解.mp4")
copy_file()

请输入你要备份的文件的数据路径:D:\重大城科\上课录屏\18_登录注册习题讲解.mp4

请输入你要保存备份文件的路径:C:\Users\WX\Desktop

import os.path as p
#需要将D:\重大城科\上课录屏\18_登录注册习题讲解.mp4视频文件被分到桌面上C:\Users\WX\Desktop\18_登录注册习题讲解.mp4
def copy_file():
    src = input("请输入你要备份的文件的数据路径:")
    dest = input("请输入你要保存备份文件的路径:")
    filename = src[src.rfind("\\")+1:]
    f = open(src,"rb")
    # ff = open(dest,"wb")
    ff = open(p.join(dest,filename),"wb")
    # ff.write(f.read())
    #以M为单位去读取  1M = 1024*1024
    while True:
        data = f.read(1024*1024)
        if  data == b"":
            print("读取完成了!!!!")
            break
        else:
            ff.write(data)
    
    f.close()
    ff.close()

# copy_file("D:\\重大城科\\上课录屏\\18_登录注册习题讲解.mp4","C:\\Users\\WX\\Desktop\\18_登录注册习题讲解.mp4")
copy_file()  #D:\\重大城科\\上课录屏\\python0316\\18_登录注册习题讲解.mp4

如果备份的文件的名称相同的情况下,会覆盖掉上一次备份的文件

使用uuid

import os.path as p
import uuid
#需要将D:\重大城科\上课录屏\18_登录注册习题讲解.mp4视频文件被分到桌面上C:\Users\WX\Desktop\18_登录注册习题讲解.mp4
def copy_file():
    src = input("请输入你要备份的文件的数据路径:")
    dest = input("请输入你要保存备份文件的路径:")
    filename = src[src.rfind("\\")+1:]
    random_uuuid = uuid.uuid4().hex
    filename = random_uuuid + filename
    f = open(src,"rb")
    # ff = open(dest,"wb")
    ff = open(p.join(dest,filename),"wb")
    # ff.write(f.read())
    #以M为单位去读取  1M = 1024*1024
    while True:
        data = f.read(1024*1024)
        if  data == b"":
            print("读取完成了!!!!")
            break
        else:
            ff.write(data)
    
    f.close()
    ff.close()

# copy_file("D:\\重大城科\\上课录屏\\18_登录注册习题讲解.mp4","C:\\Users\\WX\\Desktop\\18_登录注册习题讲解.mp4")
copy_file()  #D:\\重大城科\\上课录屏\\python0316\\18_登录注册习题讲解.mp4

也可以加上时间戳 time.time()

完成某个磁盘或者某个文件夹的备份

8.4 对象序列化

8.4.1 什么是对象序列化

对象:万物皆对象 在python中 容器(元组 列表 集合 字典) 函数

如果想要将对象持久化,保存到磁盘上,就需要对象序列化

对象序列化:将内存中像对象这种抽象的概念转换为真正字符或者字节数据存储到磁盘上

8.4.2 pickle模块

对象序列化为字节数据

>>> import pickle
>>> dir(pickle)
['ADDITEMS', 'APPEND', 'APPENDS', 'BINBYTES', 'BINBYTES8', 'BINFLOAT', 'BINGET', 'BININT', 'BININT1', 'BININT2', 'BINPERSID', 'BINPUT', 'BINSTRING', 'BINUNICODE', 'BINUNICODE8', 'BUILD', 'BYTEARRAY8', 'DEFAULT_PROTOCOL', 'DICT', 'DUP', 'EMPTY_DICT', 'EMPTY_LIST', 'EMPTY_SET', 'EMPTY_TUPLE', 'EXT1', 'EXT2', 'EXT4', 'FALSE', 'FLOAT', 'FRAME', 'FROZENSET', 'FunctionType', 'GET', 'GLOBAL', 'HIGHEST_PROTOCOL', 'INST', 'INT', 'LIST', 'LONG', 'LONG1', 'LONG4', 'LONG_BINGET', 'LONG_BINPUT', 'MARK', 'MEMOIZE', 'NEWFALSE', 'NEWOBJ', 'NEWOBJ_EX', 'NEWTRUE', 'NEXT_BUFFER', 'NONE', 'OBJ', 'PERSID', 'POP', 'POP_MARK', 'PROTO', 'PUT', 'PickleBuffer', 'PickleError', 'Pickler', 'PicklingError', 'PyStringMap', 'READONLY_BUFFER', 'REDUCE', 'SETITEM', 'SETITEMS', 'SHORT_BINBYTES', 'SHORT_BINSTRING', 'SHORT_BINUNICODE', 'STACK_GLOBAL', 'STOP', 'STRING', 'TRUE', 'TUPLE', 'TUPLE1', 'TUPLE2', 'TUPLE3', 'UNICODE', 'Unpickler', 'UnpicklingError', '_Framer', '_HAVE_PICKLE_BUFFER', '_Pickler', '_Stop', '_Unframer', '_Unpickler', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_compat_pickle', '_dump', '_dumps', '_extension_cache', '_extension_registry', '_getattribute', '_inverted_registry', '_load', '_loads', '_test', '_tuplesize2code', 'bytes_types', 'codecs', 'compatible_formats', 'decode_long', 'dispatch_table', 'dump', 'dumps', 'encode_long', 'format_version', 'io', 'islice', 'load', 'loads', 'maxsize', 'pack', 'partial', 're', 'sys', 'unpack', 'whichmodule']

dumps -------- 将对象序列化为字节数据

>>> ls = [1,2,3,4,5,6,7]
>>> type(ls)
<class 'list'>
>>> pickle.dumps(ls)
b'\x80\x04\x95\x13\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x02K\x03K\x04K\x05K\x06K\x07e.'
>>> data = pickle.dumps(ls)
>>> data
b'\x80\x04\x95\x13\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x02K\x03K\x04K\x05K\x06K\x07e.'
>>> f = open("a.dat","wb")
>>> f.write(data)
30
>>> f.close()

dump ----- 将对象序列化为字节数据,并且能够保存到文件中

>>> f.close()
>>> pickle.dump(ls,open("b.dat","wb"))

loads ------- 将字节数据反序列化为对象

>>> f = open("a.dat","rb")
>>> show = f.read()
>>> show
b'\x80\x04\x95\x13\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x02K\x03K\x04K\x05K\x06K\x07e.'
>>> pickle.loads(show)
[1, 2, 3, 4, 5, 6, 7]
>>> ls1 = pickle.loads(show)
>>> ls1
[1, 2, 3, 4, 5, 6, 7]
>>> type(ls1)
<class 'list'>

load ----- 将file反序列化为对象

>>> pickle.load(open("b.dat","rb"))
[1, 2, 3, 4, 5, 6, 7]
8.4.3 json模块

将对象序列化为字符数据

>>> d = {"username":"zhangsan","age":18,"gender":"男"}
>>> type(d)
<class 'dict'>
>>> import json
>>> dir(json)
['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_default_decoder', '_default_encoder', 'codecs', 'decoder', 'detect_encoding', 'dump', 'dumps', 'encoder', 'load', 'loads', 'scanner']
>>> json.dumps(d)
'{"username": "zhangsan", "age": 18, "gender": "\\u7537"}'
>>> s = json.dumps(d)
>>> s
'{"username": "zhangsan", "age": 18, "gender": "\\u7537"}'
>>> type(s)
<class 'str'>
>>> f = open("a.txt","w")
>>> f.write(s)
55
>>> f.close()
>>> ff = open("a.txt","r")
>>> ff.read()
'{"username": "zhangsan", "age": 18, "gender": "\\u7537"}'
>>> ff.clse()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: '_io.TextIOWrapper' object has no attribute 'clse'
>>> ff.close()
>>> ff = open("a.txt","r")
>>> dd = ff.read()
>>> dd
'{"username": "zhangsan", "age": 18, "gender": "\\u7537"}'
>>> type(dd)
<class 'str'>
>>> ddd = json.loads(dd)
>>> ddd
{'username': 'zhangsan', 'age': 18, 'gender': '男'}
>>> type(ddd)
<class 'dict'>

总结:json模块一般是用来序列化字典对象,单并不是只能序列化字典对象(Python2中只能操作字典对象)

 >>> ls
 [1, 2, 3, 4, 5, 6, 7]
 >>> json.dumps(ls)
 '[1, 2, 3, 4, 5, 6, 7]'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

璀云霄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值