1.io流概念
"io"是input stream和ouput stream的缩写:即输入输出流
主要进行点的是计算机输入和输出的操作。
一般来说,是内存与磁盘之间的输入输出(狭义)
io流操作,是一种持久化操作,是将数据持久化在磁盘
2.1.io流用法
通过open全局函数——————主要作用打开本地文件
2.1.1. 样式和语法
open("文件或路径",mode)
其中mode表示打开文件的方式,打开方式决定了可对其进行的操作。
下面是用全局函数help()找到的关于open的描述(有道翻译)。
文件是一个文本或字节字符串,它给出了名称(和路径)
如果文件不在当前工作目录)的文件
被打开或要打开的文件的整数文件描述符
包装。(如果给出了文件描述符,则在
返回的I/O对象是关闭的,除非closefd设置为False。)
Ode是一个可选字符串,用于指定文件所处的模式
打开。它默认为’r’,这意味着在文本中打开阅读
模式。其他常见的值是’w’,表示写入(截断文件if)
它已经存在),'x’用于创建和写入新文件,以及
'a’表示追加(在某些Unix系统中,这意味着所有的写入操作
附加到文件的末尾,而不管当前的查找位置)。
在文本模式下,如果没有指定编码,则使用的编码是平台
依赖:locale.getpreferredencoding(False)被调用来获取
当前区域编码。(读和写原始字节使用二进制
模式和不指定编码。)可选择的模式有:
关于mode可选值的含义:
'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
'b' binary mode
't' text mode (default)
'+' open a disk file for updating (reading and writing)
'U' universal newline mode (deprecated)
翻译:
'r'可读(默认)
'w'打开用于写入,首先截断文件
'x'创建一个新文件并打开它进行写入
'a'打开,用于写入,如果存在则追加到文件末尾
“b”二元模式
't'文本模式(默认)
'+'打开磁盘文件进行更新(读写)
'U'通用换行模式(已弃用)
小结:
第一个参数:file-----打开的文件的文件名称或路径
第二个参数:mode----打开文件的模式,默认是字符输入流
2.1.2.io流分类
根据数据流动(站在内存角度来说)的方向”
1.输入流
2.输出流 把数据保存在硬盘里根据数据的类型可分为:
1.字节流 (存储图片、音频)
2.字符流
2.1.2.io流实际使用
2.1.2.1. io操作字符数据
2.1.2.1.1. 读数据
>>> f=open("cc.txt")
>>> f.read()
'哈哈哈哈'
f.close()关流
注意:一定要关流
2.1.2.1.2. 写数据(close())
>>> f=open("aa.txt",mode="w")
>>> f
<_io.TextIOWrapper name='aa.txt' mode='w' encoding='cp936'>
>>> f.write("煞笔")
2
>>> f.close()
>>> f=open("aa.txt","w")
>>> f
<_io.TextIOWrapper name='aa.txt' mode='w' encoding='cp936'>
>>> f.write("嘿嘿嘿")
3
>>> f.close()
>>>
f.write() 返回写入的个数
close()没关流的情况下,缓存区没满的情况下,不会写入。
2.1.2.1.3. 写数据(flush())
>>> f=open("aa.txt","w")
>>> f.write("哈哈哈和嘿嘿嘿1 嘿嘿嘿1")
13
>>> f.flush()
2.1.2.1.4. 追加数据
>>> f=open("aa.txt","a")
>>> f.write("呱呱呱呱")
4
>>> f.close()
2.1.2.1.5. 新建文件并写入数据
>>> f=open("redred","x")
>>> f.write("i love she")
10
2.1.2.1.6.读二进制
>>> f=open("aa.txt","rb")
>>> f.read()
b'\xb9\xfe\xb9\xfe\xb9\xfe\xba\xcd\xba\xd9\xba\xd9\xba\xd91 \xba\xd9\xba\xd9\xba\xd
91\xdf\xc9\xdf\xc9\xdf\xc9\xdf\xc9'
2.1.2.1.7.自定义读的单元个数
>>> f=open("aa.txt","rt")
>>> f.read(2)
'王维'
>>> f=open("aa.txt","rt")
>>> f.read(1)
'王'
>>> f.read()
'维
while true:
{
masg=f.read(2)
if msg == "":
berak
else:
pass
}
2.1.2.1.8.encoding参数使用
如果编码格式不对则报错或乱码
>>> f=open("aa.txt","rt",encoding="utf-8")
>>> f.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "E:\py\lib\codecs.py", line 322, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcd in position 0: invalid continuation byte
2.1.2.1.10.小结
注意:mode=“r”
本质是默认"rt",即以字符方式操作
2.1.2.2.io操作字节数据
用b表示,字节流,binary mode
mode=“rb” mode=“wb”-----操作字节数据如(图片视频音频)
字节可以操作任何数据,字符只能操作字节数据。
2.1.2.2.1.字节数据备份
def copy(src,dest):
f=open(src,"rb")
f1=open(dest,"wb")
f1.write(f.read())
if __name__ == "__main__":
copy("D:\\python\\练习\\a3长鬣蜥.jpg","D:\\python\\a3.jpg")
不推荐这样写,如果数据过大一次是读不完的,需要优化
2.1.2.2.2.字节数据备份优化
def copy(src,dest):
f=open(src,"rb")
f1=open(dest,"wb")
# f1.write(f.read())
while True:
data=f.read(1024*1024)
if data == b"":
print("数据读取完成。");
break
else:
f1.write(data)
f1.flush()
f.close()
f1.close()
if __name__ == "__main__":
copy("D:\\python\\练习\\a3长鬣蜥.jpg","D:\\a3.jpg")
其中b""表示字节空。
2.1.2.2.3.字节数据备份再优化,输入路径
def copy():
src=input("请输入你要备份的文件路径:")
dest=input("请输入你要保存的文件路径:")
f=open(src,"rb")
f1=open(dest,"wb")
# f1.write(f.read())
while True:
data=f.read(1024*1024)
if data == b"":
print("数据读取完成。");
break
else:
f1.write(data)
f1.flush()
f.close()
f1.close()
if __name__ == "__main__":
copy()
2.1.2.2.4.字节数据备份再再优化,备份不用加文件名
import os
from os import path as p
def copy():
src=input("请输入你要备份的文件路径:")
dest=input("请输入你要保存的文件路径:")
name=src[src.rfind("\\")+1:]
dest=p.join(dest,name)
f=open(src,"rb")
f1=open(dest,"wb")
# f1.write(f.read())
while True:
data=f.read(1024*1024)
if data == b"":
print("数据读取完成。");
break
else:
f1.write(data)
f1.flush()
f.close()
f1.close()
if __name__ == "__main__":
copy()
2.1.2.2.5.字节数据备份再再优化,不覆盖(uuid)
import os
import uuid
from os import path as p
def copy():
src=input("请输入你要备份的文件路径:")
dest=input("请输入你要保存的文件路径:")
tail=src[src.rfind("."):]
name=uuid.uuid4().hex+tail
dest=p.join(dest,name)
f=open(src,"rb")
f1=open(dest,"wb")
# f1.write(f.read())
while True:
data=f.read(1024*1024)
if data == b"":
print("数据读取完成。");
break
else:
f1.write(data)
f1.flush()
f.close()
f1.close()
if __name__ == "__main__":
copy()
2.1.2.2.6.字节数据备份再再优化,时间戳
import os
import time
import uuid
from os import path as p
def copy():
src=input("请输入你要备份的文件路径:")
dest=input("请输入你要保存的文件路径:")
name=uuid.uuid4().hex+str(time.time())+src[src.rfind("\\")+1:]
dest=p.join(dest,name)
f=open(src,"rb")
f1=open(dest,"wb")
# f1.write(f.read())
while True:
data=f.read(1024*1024)
if data == b"":
print("数据读取完成。");
break
else:
f1.write(data)
f1.flush()
f.close()
f1.close()
if __name__ == "__main__":
copy()
结合遍历磁盘代码,+io操作,完成磁盘数据备份操作
2.1.2.3.对象序列化
什么是对象序列化?
列表、字典、集合、和元祖都是抽象概念,需要把对象持久化操作,所以需要序列化
是把对象这种抽象的概念持久化到磁盘上,换句话说,就是将对象转为字节和字符。
2.1.2.3.1 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’]
dump--------将对象序列化为字节数据,并保存在file中
>>> ls
[1, 2, 3, 4, 5]
>>> pickle.dump(ls,open("xx.dat","wb"))
>>> pickle.dump(ls,open("x.dat","wb"))
dumps--------将对象序列化为字节数据
>>> pickle.dumps(ls)
b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00]\x94(K\x01K\x02K\x03K\x04K\x05e.'
>>> f=open("xx.dat","xb")
>>> f.write(pickle.dumps(ls))
26
>>> f.flush()
load-----------将字节数据反序列化为对象
>>> pickle.load(open("x.dat","rb"))
[1, 2, 3, 4, 5]
loads---------将字节数据反序列化为对象
>>> f=open("xx.dat","rb")
>>> show = pickle.loads(f.read())
>>> show
[1, 2, 3, 4, 5]
show=pickle(open("a.dat","rb").read())
2.1.2.3.2 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’]
dump
>>> f=open("qq.txt","wt")
>>> json.dump(d,f)
>>> d
{'username': 'zhangsan', 'age': 18}
>>> f.flush()
dumps
>>> d={"username":"zhangsan","age":18}
>>> f=open("g.txt","wt")
>>> f.write(json.dumps(d))
35
>>> f.flush()
load
>>> json.load(open("qq.txt","rt"))
{'username': 'zhangsan', 'age': 18}
loads
>>> f=open("g.txt","rt")
>>> ss=f.read()
>>> ss
'{"username": "zhangsan", "age": 18}'
>>> json.loads(ss)
{'username': 'zhangsan', 'age': 18}
>>>
json一般是用来序列化字典对象的.