Python IO
文件打开和关闭
文件打开和关闭就是两个函数,一个open函数一个close函数
open函数的原型
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
前面说open函数返回的是一个file-like对象,但是这个file-like对象并不是固定的,这个对象的类型会随着打开mode的变化而变化。
- 以文本模式打开文件(’w’, ‘r’,’wt’,’rt’等),返回一个TextIOWrapper。
- 当用二进制模式打开文件时,返回的对象也会变化。
- 在二进制读取模式,返回一个BufferedReader。
- 在二进制写模式和二进制追加模式,返回一个BufferedWriter。
- 在二进制读/写模式下,返回一个BufferedRandom。
文件读写
文件读写主要是read和write及其变种,文件的读写依赖于open函数的mode参数。
open函数的mode参数
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)
说明:
- 当mode=’x’时,如果文件不存在,则会抛出异常 FileExistsError。
- 当mode=’w’时,只要打开了文件,即使不写入内容,也会先清空文件。
- 当mode包含+时, 会增加额外的读写操作, 也就说原来是只读的,会增加可写的操作, 原来是只写的,会增加可读的操作,但是+不改变其他行为。
mode=t&mode=b
文件指针
当打开文件的时候, 解释器会持有一个指针, 指向文件的某个位置,当我们读写文件的时候,总是从指针处开始向后操作,并且移动指针。当mode=r时, 指针是指向0(文件开始),当mode=a时, 指针指向EOF(文件末尾)
和文件指针相关的两个函数是tell
函数和seek
函数
tell函数
返回当前流的位置,对于文件来说,就是文件流的位置,即文件指针的位置。
seek函数
改变文件流的位置,并返回新的绝对位置。
关于文件指针的总结
当seek超出文件末尾, 不会有异常, tell也会超出文件末尾, 但是写数据的时候,还是会从文件末尾开始写
write 操作 从 min(EOF, tell())处开始
- 文件指针按字节操作(无论是字符模式还是字节模式)
- tell方法返回当前文件指针位置
- seek方法移动文件指针
- whence 参数 SEEK_SET(0) 从0开始向后移动offset个字节, SEEK_CUR(1) 从当前位置向后移动offset个字节, SEEK_END(2) 从EOF向后移动offset个字节
- offset是整数
- 当mode为t时, whence为SEEK_CUR或者SEEK_END时, offset只能为0
- 文件指针不能为负数
- 读文件的时候从文件指针(pos)开始向后读
- 写文件的时候从min(EOF,pos)处开始向后写
- 以append模式打开的时候,无论文件指针在何处,都从EOF开始写
文件缓冲区
文件缓冲区由open函数的buffering参数决定,buffering表示缓冲方式,参数默认值为-1,表示文本模式和二进制模式都是采用默认的缓冲区。
buffering=-1
- 二进制模式: DEFAULT_BUFFER_SIZE
- 文本模式: DEFAULT_BUFFER_SIZE
buffering=0
buffering=1
- 二进制模式: 1
- 文本模式: line buffering
buffering>1
- 二进制模式:buffering
- 文本模式: DEFAULT_BUFFER_SIZE
总结
上下文管理
上下文管理,会在离开时自动关闭文件, 但是不会开启新的作用域。
上下文管理除了with open('./hello.py') as f:
这种写法外,还有另外一种写法
File-like对象
像open()
函数返回的这种有个read()
方法的对象,在Python中统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等。常见的有StringIO和BytesIO。
StringIO
StringIO顾名思义就是在内存中读写str。
要把str写入StringIO,我们需要先创建一个StringIO对象,然后项文件一样写入并读取。file支持的操作StringIO基本都是支持的。
要读取StringIO,可以用一个str初始化StringIO,然后,像读文件一样读取:
BytesIO
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。
BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:
和StringIO类似,可以用一个bytes初始化BytesIO,然后,像读文件一样读取:
路径操作pathlib
路径操作有os.path和pathlib两种方式。
- os.path是已字符串的方式操作路径的:
import os
- pathlib是面向对象设计的文件系统路径:
import pathlib
pathlib在python3.2以上开始默认支持,在python2.7中如果要使用pathlib需要安装
pathlib模块的源代码见:Lib/pathlib.py
目录操作
pathlib目录的基本使用是pathlib模块中的Path这个类。
通过help(pathlib.Path)
可以查看到Path类的各个Methods。
目录操作的几个函数:
is_dir(self)
:判断路径是否是目录iterdir(self)
:生成当前路径下所有文件(包括文件夹)的生成器,但是不会yield ‘.’ 和’..’这两个路径mkdir(self, mode=511, parents=False, exist_ok=False)
:删除当前目录,可以指定modermdir(self)
:删除目录,并且目录必须为空,否则会报错
使用示例如下
通用操作
主要是一些路径的通用操作
文件复制移动删除
使用shutil
模块即可
- shutil.copyfileobj # 操作对象是文件对象
- shutil.copyfile # 仅复制内容
- shutil.copymode # 仅复制权限
- shutil.copystat # 仅复制元数据
- shutil.copy # 复制文件内容和权限 copyfile + copymode
- shutil.copy2 # 复制文件内容和元数据 copyfile + copystat
- shutil.copytree # 递归复制目录
- shutil.rmtree # 用于递归删除目录
- shutil.move # 具体实现依赖操作系统, 如果操作系统实现了 rename系统调用, 直接走rename系统调用,如果没实现,先使用copytree复制, 然后使用rmtree删除源文件
序列化和反序列化
- 序列化: 对象转化为数据
- 反序列化: 数据转化为对象
Python私有协议pickle
pickle 是Python私有的序列化协议
pickle源代码见:lib/python3.5/pickle.py
主要函数
dumps
对象导出为数据,即序列化loads
数据载入为对象,即反序列化,反序列化一个对象时,必须存在此对象的类
通用的json协议
JSON格式支持的数据类型如下
类型 | 描述 |
---|
Number | 在JavaScript中的双精度浮点格式 |
String | 双引号的反斜杠转义的Unicode,对应python中的str |
Boolean | true 或 false |
Array | 值的有序序列,对应python中的list |
Value | 它可以是一个字符串,一个数字,真的还是假(true/false),空(null )等 |
Object | 无序集合键值对,对应python中的dict |
Whitespace | 可以使用任何一对中的令牌 |
null | empty |
使用示例如下
json参考:JSON 数据格式