Python文件打开模式详解:r、w、a及读写权限与指针操作
本文详细解析Python中文件打开模式r、w、a及其组合r+、w+、a+的行为差异,重点探讨读写权限、文件创建条件及指针位置对读取结果的影响。通过实例说明因指针位于文件末尾导致的读取空值或乱码问题,并提供seek重置指针与with语句规范操作的解决方案,帮助开发者避免常见文件IO错误。
本文通过具体实例深入解析Python中文件打开的各种模式,旨在帮助读者清晰理解不同模式的特性与适用场景,供学习参考。
Python文件打开模式基础辨析
首先需排除因文件打开模式选择错误导致的问题。
理解基础模式:r代表只读,r+代表读写但不创建新文件;若文件不存在,r模式会报错。
w代表新建并只写,w+代表新建并读写。这两种模式在打开文件时,都会将原有文件内容清空。
注意以w模式打开的文件无法读取内容,而w+模式则支持读写操作。
进一步辨析w+与r+的核心区别。
r+模式允许读写,但如果目标文件不存在,程序会报错;而w+模式同样允许读写,若文件不存在则会自动创建新文件。
接着分析r+与a+模式的区别。
fd = open("1.txt",'w+')
fd.write('123')
fd = open("1.txt",'r+')
fd.write('456')
fd = open("1.txt",'a+')
fd.write('789')
观察以下代码执行后的输出结果。
456789
上述结果说明,使用r+模式写入时,新内容覆盖了文件原有的部分数据。
当以a或a+模式打开文件时,采用的是附加(追加)方式。
a模式为附加写方式,不支持读取;a+模式为附加读写方式,支持读取。
使用'U'标志打开文件时,所有行分割符在通过Python输入方法(如read()系列)返回时,都会被统一替换为换行符\n。'rU'模式同时也支持'rb'二进制选项。
r模式和U模式均要求目标文件必须已经存在,否则无法打开。
w模式和a模式属于不可读的打开方式。
若文件不存在会自动创建新文件的方式包括:a、a+、w、w+。
>>> fd=open(r'f:\mypython\test.py','w') #只读方式打开,读取报错
>>> fd.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: File not open for reading
>>> fd=open(r'f:\mypython\test.py','a')#附加写方式打开,读取报错
>>> fd.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: File not open for reading
>>>
文件指针导致的读写异常与解决
其次,解决正确读写方式下出现乱码的问题。
>>> fd=open(r'f:\mypython\test.py','a+')
>>> fd.write('123')
>>> fd.read()
>>> fd.close()
在调用close之前手动打开文件,发现没有写入内容;而在close之后手动打开文件,则看到乱码:123嚅?。
原因分析主要涉及指针位置问题。open()以a+模式开启一个附加读写模式的文件,由于是a特性,文件指针位于文件末尾。此时如果执行read(),Python发现指针位置即为EOF(文件结束符),因此读取到空字符串。
在写入“123”之后,指针位置变为4,仍处于文件尾,内存中的文件状态显示为123[EOF]。
但在执行read()时,Python仍然尝试在磁盘文件上,将指针从文件头向后移动3个字符,然后读取直到EOF为止。
这意味着,实际上你跳过了该文件真正的EOF,对硬盘底层数据进行了dump操作,一直dump到了从前存盘文件的[EOF]位置。因此,最后得到了一些意想不到的随机乱字符,而非单纯的编码错误导致的乱码。
解决方案:在读取之前,将指针重置为文件头(注意:如果读取之后重置指针再读,操作无效)。
>>> fd=open(r'f:\mypython\test.py','a+')
>>> fd.seek(0)
>>> fd.read()
'123'#顺利读出
读取空字符的原因与seek重置
第三类问题:文件明明有内容,却读出了空字符。
>>> fd=open(r'f:\mypython\test.py','w+') #清空内容,重新写入
>>> fd.write('456')
>>> fd.flush()#确定写入,此时文件内容为“456”
>>> fd.read()
'' #读出空
原因同样是指针问题:写入操作后,指针指向文件末尾[EOF],因此直接读取会得到空结果。
解决方案一:调用close后重新打开文件,此时指针位于文件开头。(r、r+、a+、U模式均可,注意避免使用w、w+、a模式)。
>>> fd.close()
>>> fd=open(r'f:\mypython\test.py','a+')
>>> fd.read()
'456'
>>> fd.close()
>>> fd=open(r'f:\mypython\test.py','r+')
>>> fd.read()
'456'
>>> fd.close()
>>> fd=open(r'f:\mypython\test.py','r')
>>> fd.read()
'456'
>>> fd.close()
>>> fd=open(r'f:\mypython\test.py','U')
>>> fd.read()
'456'
解决方案二:调用seek函数将指针指向文件开头。
>>> fd=open(r'f:\mypython\test.py','w+')
>>> fd.write('456')
>>> fd.seek(0)
>>> fd.read()
'456'
关于seek函数的用法。
seek(offset[, whence]) ,其中offset是相对于某个位置的偏移量。位置由whence参数决定,默认whence=0,表示从文件开头起算;whence=1,表示从当前位置算起;whence=2表示相对于文件末尾移动,通常此时offset取负值。
规范关闭文件与with语句使用
最后,务必记得调用close()关闭文件。
当我们写入文件时,操作系统通常不会立即将数据写入磁盘,而是先存入内存缓存,待空闲时再慢慢写入。只有调用close()方法时,操作系统才保证将未写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写入了一部分,剩余部分丢失。因此,推荐使用with语句来确保文件安全关闭:
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')
参考评论区补充:对于'r+'模式,如果先读取内容再写入,行为类似于追加模式;如果直接写入内容,则是覆盖模式。
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python文件与目录操作技巧汇总》、《Python文本文件操作技巧汇总》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》。
希望本文所述的Python文件操作技巧对大家有所帮助。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









