深入解读Python如何进行文件读写
作者:微小冷
open
Python提供了非常方便的文件读写功能,其中open
是读写文件的第一步,通过open
读写文件的方式和把大象装冰箱是一样的
f = open("test.txt",'w') #第一步,把冰箱门(文件)打开 f.write("this is content") #第二步,把大象(文件内容)装进去 f.close() #第三步,把冰箱门关上,否则大象可能会跑掉
open
的定义方式为
file=open(path,mode='r',buffering=-1,encoding=None)
其中,
path
为文件路径mode
为读取模式,默认为r
,即只读模式。buffering
为缓冲区,由于内存的读写速度快于外设,所以大部分情况不用设,即不大于0。encoding
为编码方式- 最后,输出的
file
是一个文件对象。
其中,mode
包括以下几种
r | r+ | w | w+ | a | a+ | |
---|---|---|---|---|---|---|
b | rb | rb+ | wb | wb+ | ab | ab+ |
其中,b表示二进制,r表示读,w表示写,a表示追加。无论什么模式,有+
则意味着可读可写。写入一般会覆盖原文件,追加则在原文件尾部开始写。如果文件不存在,w, w+, a, a+, wb
会创建新文件。
文件对象
通过open
创建的文件对象,除了用于关闭文件的close
之外,有两组最常用的函数,即代表读写的read
和write
,分别用于读写,其区别如下
read | write | 读写整个文件 read(size)可读取size大小的文件 |
readline | 每次读一行 由于write直接输入字符串,故不必设置writeline |
|
readlines | writelines | 前者按行读取文件,并存入一个字符串列表 writelines将一个字符串列表的形式写入文件 |
例如
>>> f = open('test.txt','w') >>> f.writelines(['a','b','c\n','d']) >>> f.close() >>> f = open('test.txt','r') >>> f.readlines() ['abc\n', 'd'] #在写lines的时候,并不会自动添加\n >>> f.close()
根据我电脑的性能,读取500M的txt就要超过1s,读取2G的文件多半要报错。这个时候需要通过seek
函数来指定偏移量,然后在偏移处的位置对文件进行读写操作。其输入为f.seek(offset,whence=0)
其中
offset
为偏移量whence
为偏移方式,为0时表示绝对定位;为1时表示相对定位;为2表示从末尾定位。
从seek
的视角来看,open
文件时,如果用了w
,则代表seek(0)
,如果用了a
,则代表seek(0,2)
。
通过tell
可以返回当前偏移量,相当于seek
的对偶函数。
在对文件操作结束后,需要使用f.close()
将缓存中的字符串写入硬盘;如果害怕发生意外,可以用f.flush()
强制写入。
此外,文件对象的成员变量如下
name | mode | encoding | error | closed | buffer |
---|---|---|---|---|---|
文件名 | 读写模式 | 编码方式 | 错误模式 | 是否已经关闭 | 缓冲区 |
此外还有三个判定函数
readable() |
writable() |
seekable |
---|---|---|
是否可读 | 是否可写 | 可否指定偏移量 |
with … as表达式
在写入文件时,如果忘了close
或者flush
,那么可能还有一些数据留在内存中,从而导致我们得到的文件是残缺的。
with as
表达式可以通过调用对象中的__enter__
方法和__exit__
方法,来更加智能地调用close
,从而免除了忘写close
的麻烦。其调用方法为
with open('text.txt','w') as f: f.write("12345")
查看file.py
,其__exit__
函数正是close
:
def __enter__(self): return self def __exit__(self, type, value, traceback): self.close()
底层实现:os.open
open
是非常方便的函数,但开销也很大,毕竟直接返回了一个文件对象。相比之下,其底层实现os.open
返回的是一个整型的文件ID,对于在速度上有要求的频繁的文件读写操作,可以考虑使用。
os
中,打开一个文件的方法为
fd = os.open(path, flags, mode=511, dir_fd=None)
其中,
path
为文件路径flags
为打开标志,例如os.O_RDONLY
代表只读、os.O_WRONLY
代表只写mode
表示文件权限,例如777代表任何人可读可写可执行;511代表文件创建者可读可执行,其他人只可读,这属于Linux的内容,日后可专门在Linux里说。dir_fd
表示相对路径的规则,为自定义函数,比较少用。- 最后,输出的
fd
是某个文件的标识。
其中,mode的取值可见于deepin和windows的手册,常用的标志如下,多个标志可通过|
叠加,这一股浓郁的C风确认来自操作系统无疑了。
os.open | open | os.open | open |
---|---|---|---|
os.O_RDONLY | ‘r' | os.O_WRONLY | ‘w' |
os.O_RDWR | ‘r+' | os.O_APPEND | ‘a' |
os.O_CREAT | 创建并打开 |
其中相关的函数还有:
os.fdopen(fd, mode, bufsize) |
通过fd创建一个文件对象,并返回这个文件对象 |
os.read(fd, n) |
从fd 中读取最多 n 个字节并返回,如果fd对应文件已达到结尾, 则返回空串。 |
os.write(fd, str) |
将str 写入fd,返回实际写入的字符串长度 |
os.fsync(fd) |
强制将fd所对应的文件写入硬盘 |
os.close(fd) |
关闭fd |
os.dup(fd) |
复制fd |
os.dup2(fd, fd2) |
将fd1所对应的文件复制给fd2 |
os.fstat(fd) |
返回fd的状态 |
os.ftruncate(fd, length) |
裁剪fd, length 不大于文件尺寸 |
os.isatty(fd) |
如果fd已经打开,同时与tty(-like)设备相连,则返回True, 否则False。 |
os.lseek(fd, pos, how) |
设置fd当前位置为pos, how为修改方式,等同于前文中的whence |
到此这篇关于深入解读Python如何进行文件读写的文章就介绍到这了,更多相关Python 文件读写内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!