python - 文件 IO 读写
一、文件常用操作
1. 绝对路径和相对路径
绝对路径
从根文件夹开始,Windows 系统中以盘符(C:\ D:)作为根文件夹,而 OS X 或 Linux 系统中以 \ 作为根文件夹。相对路径
指文件相对于当前工作目录所在的位置。
‘.’:当级目录
‘..’:上级目录
当前目录:\plumrx\test
文件目录:\plumrx\test\test1\demo.txt
相对路径可表示为:.\test1\demo.txt
2. 文件应用级操作三部曲
1.1 open
open()函数用于创建或打开指定文件。
1.2 读写操作
1.3 close
1 | f = open("14-practice.py") |
3. open()函数
open()函数用于创建或打开指定文件。
格式:
file = open(file_name[, mode=’r’[, buffering=-1[, encoding = None]]])
除了 file_name 其余为可选参数,具体含义如下:
file:要创建的文件对象。
file_name:要创建或打开的文件名称,需使用引号括起,使用对应路径。
mode:指定文件的打开模式,不填写则默认为 r ,只读。
encoding:手动设定打开文件时使用的编码格式。
4. 文件读取
read()
逐字读取文件中的内容。file.read([size])
size 默认为所有内容readline()
逐行读取,以 ‘\n’ 作为读取一行的标志file.readline([size])
size 指定读取每一行时,一次最多读取的字数。readlines()
读取所有行,读取结果为一个列表,每一行为其中一个元素。file.readlines()
5. 文件写入
- write()
想文件中写入指定内容。1
2
3
4
5
6
7
8
9
10
11
12格式:
file.write(string)
样例:
f = open('test.txt','w')
f.write('test1\n')
f.write('test2\n')
f.write('test3')
-----------------
test1
test2
test3 - writelines()
将字符串列表写入文件中,每个元素之间换行。1
2
3
4
5
6
7
8文件复制,将test1.txt -> test2.txt
f_read = open('test.txt')
f_write = open('test-copy.txt', 'w')
f_write.writelines(f_read.readlines())
f_read.close()
f_write.close()
6. seek()和tell()
tell()
用于判断文件指针当前所处的位置。file.tell()
seek()
用于移动文件指针到指定位置。file.seek(offset[,whence])
offset:
偏移量,可正可负,正数代表向后偏移,负数代表向前
whence:
0:文件开头
1:当前位置
2:文件末尾
1 | # 设置当前指针位置为5 |
7. whith as 读写文件
作用:操作上下文管理器,自动分配且释放资源。
1 | with 表达式[as target]: |
8. fileinput 模块:逐行读取多个文件
多文件读写的时候,可以查询文件的位置。
- input 函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33--------- 单文件用法 -----------
import fileinput
for line in fileinput.input('test.txt'):
print(line, end='')
--------------------
test1
test2
test3
--------- 多文件用法 -----------
for line in fileinput.input(files=('test.txt','test-copy.txt')):
print(line,end='')
fileinput.close()
---------------------
test1
test2
test3TEST1
TEST2
TEST3
--------- 文件内容替换 & 备份 -----------
for line in fileinput.input('test.txt', backup='.bak', inplace=True):
print(line.replace('te', 'TE'))
---------------------
TEst1
TEst2
TEst3
9. linecache 模块:读取文件制定行
指定行号即可
1 | import linecache |
二、读取大文件(GB)编码技巧
问题:open()和read()函数仅适用于小文件的读取。文件过大,会造成内存溢出。
解决办法:反复调用read(size)方法,每次指定读取字数。
1 | 伪码: |
尝试读取本地500M的大文件
生成一个超过500M的文件,具体方法可以参考:
https://plumrx.github.io/2022/07/22/狗屁不通文章生成器/读取文件
1
2
3
4
5with open('狗屁不通文章.txt') as file:
while True:
block=file.read(1024)
if not block:
break
三、python异常检测和处理
异常官方指引文档:https://docs.python.org/3/library/exceptions.html#base-classes
语法类错误
- 函数调用语法错误
1
2
3print "test"
-----------------
SyntaxError: Missing parentheses in call to 'print'. Did you mean print("test")?
运行时错误
建立在语法正确的情况下,才会发生运行错误。
read()函数抛出 UnicodeDecodeError异常
原因:目标文件使用的编码格式与open()函数打开该文件使用的编码格式不匹配。
解决方案:在调用open()函数时,加上对应编码的参数。a = 1/0
0作为除数没有意义,所以运行后产生错误。
异常处理
try except 异常捕获
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58# 1.1 万能异常捕获
try:
a = 1
print(a / 0)
except Exception:
print('error')
---------------------
error
# 1.2 指定异常捕获
将异常的信息存储在变量 e 中
try:
f = open('file_miss', 'r')
except IOError as e:
print('open exception: %s: %s' % (e.args, e.strerror))
---------------------
open exception: (2, 'No such file or directory'): No such file or directory
# 1.3 指定多个异常
# 可以衔接多个 except ,以便区分多种报错类型。
try:
a = int(input('输入被除数:'))
b = int(input('输入除数:'))
c = a / b
print('商:', c)
except (ValueError, ArithmeticError) as e:
print('数字格式 or 算术异常')
except :
print('other error')
----------------------
输入被除数:1
输入除数:0
数字格式 or 算术异常
# 1.4 异常 & 正常流程的捕获
try:
a = int(input('输入被除数:'))
b = int(input('输入除数:'))
c = a / b
print('商:', c)
except (ValueError, ArithmeticError) as e:
print('数字格式 or 算术异常')
else:
print('everything is OK')
--------------------------
输入被除数:1
输入除数:1
商: 1.0
everything is OKtry except finally:资源回收
功能:无论 try 块是否发生异常,都要进入 finally 语句,并执行其中代码。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18try:
a = int(input('输入被除数:'))
b = int(input('输入除数:'))
c = a / b
print('商:', c)
except (ValueError, ArithmeticError) as e:
print('数字格式 or 算术异常')
else:
print('everything is OK')
finally:
print('over')
-------------------------
输入被除数:0
输入除数:9
商: 0.0
everything is OK
overraise:主动触发异常
功能:一旦执行 raise 语句,raise 后面的语句将不能执行。1
2
3
4
5
6
7
8
9
10
11
12
13
14try:
a = input('please input a number:')
if (not a.isdigit()):
raise ValueError('a must be a number')
except ValueError as e:
# repr() 函数将对象转化为供解释器读取的形式
# repr() 方法可以将读取到的格式字符,比如换行符、制表符,转化为其相应的转义字符。
print('create error', repr(e))
pass
-----------------------------
please input a number:a
create error ValueError('a must be a number')sys.exc_info():获取异常信息 - 一般详细
1
2
3
4
5
6
7
8
9
10
11
12import sys
try:
print(1 / 0)
except Exception as e:
print(e)
print(sys.exc_info())
--------------------------
division by zero
(<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero'), <traceback object at 0x10b889f00>)traceback 模块:获取异常信息 - 非常详细
直接将异常全部打印出来
1 | import traceback |