1 Python文件IO操作
常用操作如下表:
clumn | column |
---|---|
open | 打开 |
read | 读取 |
write | 写入 |
close | 关闭 |
readline | 行读取 |
readlines | 多行读取 |
seek | 文件指针操作 |
tell | 指针位置 |
1.1 open
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
示例
f = open('test')
print(f.read())
f.close()
文件操作中,最常用的就是读和写。
文件访问的模式有两种:文本模式和二进制模式。不同模式下,操作函数不尽相同,表现的结果也不一样。
open函数的参数
- file 打开或者要创建的文件名,如果不指定路径,默认是当前路径
- mode模式
模式 | 描述 |
---|---|
r 模式 | 只读打开文件,如果使用write方法,则会抛出异常;如果文件不存在,抛出FileNotFoundError异常 |
w | 只写打开,如果读取则抛出异常;如果文件不存在,则直接创建文件;如果文件存在,则清空文件内容 |
x | 文件不存在,创建文件,并只写方式打开;文件存在,抛出FileExistsError异常 |
a | 文件存在,只写打开,追加内容;文件不存在,则创建后,只写打开,追加内容 |
r只读,wxa都是只写 | wxa都可以产生文件,w不管文件存在与否,都会生成全新内容的文件;a不管文件是否存在,都能在打开的文件尾部追加;x必须要求文件事先不存在,自己造一个文件。 |
文本模式t | 字符流,将文件的字节按照某种字符编码理解,按照字符操作。默认模式。 |
二进制模式b | 字节流,将文件按照字节理解,与字符编码无关。二进制模式操作时,字节操作使用bytes类型。 |
- 文件指针
mode = r 指针起始在0
mode = a 指针起始在EOF(文件末尾)
- seek(offset[,whence]) 移动指针. offset偏移多少字节。
文本模式下:
whence 0 缺省值,表示从头开始,只接受正整数
whence 1 表示从当前位置 ,只接受0
whence 2表示从EOF位置开始,只接受0
字节模式:
wence 0 缺省值,表示从头开始,offset只接受正整数
whence 1 表示从当前位置 ,offset可正可负
whence 2表示从EOF位置开始,offset可正可负
1.2 常用函数
函数 | 说明 |
---|---|
read(size=-1) | 默认读取所有,文本模式下为读取字符数量,字节模式下为字节数 |
readline(size=-1) | 一次读取多少行内容,默认所有 |
readlines | 读取多行内容 |
write(s) | 把字符串s写入到文件中,并返回字符的个数 |
close() | flush并关闭文件对象,关闭后,再次关闭没有效果 |
1.3 其他函数
函数 | 说明 |
---|---|
seekable() | 是否可seek |
readable() | 是否可读 |
writeabel() | 是否可写 |
closed() | 是否已经关闭 |
2 上下文管理
先看一个例子
lst = []
for _ in range(2000):
lst.append(open("test"))
# OSError: [Errno 24] Too many open files:'test'
print(len(lst))
ulimit -a 查看所有限制,其中open files 就是打开的文件数限制,默认1024。
(base) zhaow@zhaow-610:~$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 62945
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 62945
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
解决办法:
1.异常处理
当出现异常的时候,拦截异常,但是很多代码都可能出现OSError异常,还不好判断异常就是因为资源限制产生的。
f = open('test')
try:
f.write('abc')
finally:
f.close()
使用finally 可以保证所有文件可以被关闭。
上下文管理
一种特殊的语法,交给解释器去释放文件。
with open('test') as f:
f.read()
使用with...as关键字:
上下文管理语句并不会开启新的作用域
with语句块执行完的时候,会自动关闭文件对象
对应类似文件对象的IO对象,一般来说都需要在使用完的时候关闭、注销,以释放资源。
IO被打开的时候,会获得的文件描述符fd,但计算机资源是有限的,所以操作系统都会做限制,目的是为了保护计算机资源不要被完全耗尽。
一般情况下,除非特别明确的知道资源情况,否则不要提高资源的限制来解决问题。
3.StingIO和BytesIO
- StingIO
io模块中类: from io import StringIO
内存中,开辟的一个文本模式的buffer,可以像文件对象一样操作它
当close方法被调用的时候,这个buffer会被释放
getvalue() 获取全部内容,跟文件指针没有关系
示例
from io import StingIO
sio = StringIO() # 跟文件操作类似
sio.write("test context")
sio.seek(0)
print(sio.getvalue())
print(sio.readline())
sio.close()
- BytesIO
io模块中类: from io import BytesIO
内存中,开辟的一个二进制模式的buffer,可以像文件对象一样操作它
当close方法被调用的时候,这个buffer会被释放
getvalue() 获取全部内容,跟文件指针没有关系
与StringIO相似。
一般来说,磁盘操作比内存操作慢的多,内存足够的情况下,一般的优化是少落地,减少磁盘IO的过程,可大大提高程序的运行效率。
4. 路径操作
3.4版本之前:os.path模块
示例1
from os import path
p = path.join('/etc'. 'sysconfig', 'network')
print(type(p), p)
print(path.exists(p))
print(path.split(p))
print(path.abspath('.'))
p = path.join('o:/', p, 'text.txt')
print(path.dirname(p))
print(path.basename(p))
print(path.splitdrive(p)) # window下使用
3.4版本之后:pathlib模块
示例1
from pathlib import Path
p = Path()
p.absolute() #绝对路径
p = p.joinpath('a','b')
p.absolute()
p = p / 'c' #拼接 等价于 p / = 'c' , p = p.joinpath('c')
#目录初始化
p = Path() #当前目录
p = Path('a', 'b', 'c/d') #当前目录下a/b/c/d
p = Path('/etc')