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')