文件读写操作

Zss 发表于:
文件的操作,步骤为:打开一个文件–>读取/写入内容–>保存文件

1.使用  with open(path,’r’) as f:语句来打开文件时,切记不能将f命名为file,py里自带有这个关键字了,没注意坑了好久。。。

2.在使用with open(path,’r’) as f:,这个语句在读取完文件后,最后会自带一个close()的操作,也就是说只有在这个语句下的一个缩进里面才允许操作,不然文件就已经关闭了

当return  test时程序正常所以是需要在这个话里面来操作才是正确的

def openfile(path):
    test = []
    with open(path,'r') as f:
        for i in f.readlines():
            test.append(i)
    return f.readlines()

if __name__ == '__main__':
    test = openfile('zss.txt')
    print(test)

报错:Traceback (most recent call last):
 File "C:/Users/Zss-pc/Desktop/Py/a.py", line 13, in <module>
 test = openfile('zss.txt')
 File "C:/Users/Zss-pc/Desktop/Py/a.py", line 10, in openfile
 return f.readlines()
ValueError: I/O operation on closed file
或者以这种形式来写
test = []
f = open(path,'a')
for i in f.readlines():
    test.append(i)
f.close()

3.在py2中下面语句运行错误,但是py3中正常,不加encoding=’utf-8’py2正常

f = open(path,'a',encoding='utf-8')

data_file = open(“F:\MyPro\data.yaml”, “r”, encoding=’utf-8’)

运行的时候报错:TypeError: ‘encoding’ is an invalid keyword argument for this function

网上查找一番后,改成如下这样就可以搞定
import io

data_file = io.open(“F:\MyPro\data.yaml”, “r”, encoding=’utf-8’)

但是我却遇到另外一个问题,暂时还未得到解决

def openfile(path):
    test = []
    f = io.open(path,'a',encoding='utf-8')
    for i in f.read():
        test.append(i)
    f.close()
    return test

if __name__ == '__main__':
    test = openfile('zss.txt')
    print(test)

报错IOError: not readable

实例:zss.txt文件如下

11111
22222
33333
44444
55555
def openfile(path):
    test = []
    with open(path,'r') as f:
        s = f.read()       #read方法将文件一次全部读取,为一个字符串  如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)方法,每次最多读取size个字节的内容
 return s

if __name__ == '__main__':
 test = openfile('zss.txt')
 print(test)
 print(type(test))

输出:
11111
22222
33333
44444
55555
<type 'str'>


若改成f.readlines() 则是读取所有文件 换行符,空格啥的也有,输出为列表,每行的信息为一个元素组成一个列表
输出:
['11111\n', '22222\n', '33333\n', '44444\n', '55555']
<type 'list'>

若改为f.readline(),读取文件的第一行 输出字符串 为第一行的内容
输出:
11111
<type 'str'>

 

如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便:

for line in f.readlines():
    print(line.strip()) # 把末尾的'\n'删掉
写文件

写文件和读文件是一样的,唯一区别是调用open()函数时,传入标识符'w'或者'wb'表示写文本文件或写二进制文件:

>>> f = open('/Users/michael/test.txt', 'w')
>>> f.write('Hello, world!')
>>> f.close()

你可以反复调用write()来写入文件,但是务必要调用f.close()来关闭文件。当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with语句来得保险:

with open('/Users/michael/test.txt', 'w') as f:
    f.write('Hello, world!')

要写入特定编码的文本文件,请给open()函数传入encoding参数,将字符串自动转换成指定编码

字符编码

要读取非UTF-8编码的文本文件,需要给open()函数传入encoding参数,例如,读取GBK编码的文件:

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')
>>> f.read()
'测试'

遇到有些编码不规范的文件,你可能会遇到UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,open()函数还接收一个errors参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略:

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')
二进制文件

前面讲的默认都是读取文本文件,并且是UTF-8编码的文本文件。要读取二进制文件,比如图片、视频等等,用'rb'模式打开文件即可:

>>> f = open('/Users/michael/test.jpg', 'rb')
>>> f.read()
b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节