python文件对象几种操作模式区别——文件操作方法详解
文件对象的字节模式/b模式(以utf-8编码为例) |
|||
|
读操作 |
写操作 |
指针操作 |
ASCII字节 |
返回bytes/字节类型的Ascii |
写入bytes类型字节 例如:b'This is ascii' |
使用seek每次设置任意字节 |
中文字符串 |
返回bytes/字节类型的乱码 需要解码后显示 例如:'\xe4\xbd\xa0'.decode('utf-8') |
把字符串编码后才可写操作 例如:'内容'.encode('utf-8') |
使用seek每次设置3的倍数的字节 |
文件对象的文本模式 |
|||
|
读操作 |
写操作 |
指针操作 |
ASCII字节 |
返回可查看的字符串 |
写入查见的字符串 |
使用seek每次设置任意字节 |
中文字符串 |
返回可查看的字符串 |
写入查见的字符串 |
使用seek每次设置3的倍数的字节 |
模式 |
文件存在 |
文件不存在 |
操作 |
文件内容 |
r |
创建open对象正常正常打开 |
创建open对象报错无法读取原文件 |
只读 |
只可读不可写,默认就是r模式。 可以用指针调节位置去读。 |
w |
创建open对象正常原文件内容直接清空 |
创建open对象正常创建新文件 |
只写 |
打开文件时,内容就被清空。可以调节指针位置去写。 |
a |
创建open对象正常正常打开 |
创建open对象正常创建新文件 |
只写 |
不覆盖原文件内容。只能在末尾追加内容,调节指针无法改变写的位置。如果不写内容,原文件不变。 |
r+ |
创建open对象正常正常打开 |
创建open对象报错无法读取原文件 |
读写 |
不覆盖原文件内容。指针默认在末尾追加内容,指针在其它位置写操作时,覆盖原文件内容。如果不写内容,原文件不变。根据指针位置读文件 |
w+ |
创建open对象正常原文件内容直接清空 |
创建open对象正常创建新文件 |
读写 |
打开文件时,内容就被清空。写操作覆盖之前的文件内容。根据指针位置读文件 |
a+ |
创建open对象正常正常打开 |
创建open对象正常创建新文件 |
读写 |
指针默认在末尾,写文件只能追加内容,根据指针位置读文件。如果不写内容,原文件不变。 |
备注:只要是可写模式,在关闭文件之前,都可以多次调用write方法追加内容 |
详细的讲解
一、文件的操作
操作文件大概流程过程,文件是否存在,打开文件,读写文件,关闭文件
1 >>> import os 2 >>> os.path.isfile('wdwj') #不存在 3 False 4 >>> f=open('wdwj','w')#用'w'写的方式打开文件,不存在就自动创建 5 >>> f.write('我的文件内容')#写文件内容 6 6 7 >>> f.close()#关闭文件 8 >>> os.path.isfile('wdwj')#已经成功创建 9 True 10 >>> with open('wdwj') as f: #使用with 打开文件后,自动关闭文件 11 ... data=f.read() 12 ... 13 >>> print(data) 14 我的文件内容
python3 就是open 没有file
查看/设置系统文件编码集
import sys
sys.getdefaultencoding()
sys.setdefaultencoding("utf-8")
关于文件操作的编码问题。
在windows下:在pycharm当中设置基本编码是utf-8,在pycharm里新建文本文件就是utf-8,
然后运行pycharm程序,读取这个文本文件就会出错,它会使用windows默认GBK编码去读取。
打开文件
f = open('musictxt',encoding='utf-8')#encoding='utf-8'不加这个参数的话,就按当前系统编码集
open方法详细参数
def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
打开文件的模式,上文中的表格里有更详细的说明
r,只读模式(默认)。
w,只写模式。
a,追加模式。
通常文件以文本打开,读写文件的字符串都会被特定的编码方式(默认是UTF-8)编码。
模式后面加'b',读写文件都以字节方式读写。常见的JPG、EXE等数据文件使用。
文本模式下,换行时根据操作系统不同,换行也不同Unix上是 \n , Windows上是 \r\n。注意,文本操作时影响不大。但以字节模式操作时,会影响数据。
二、文件对象方法
文件读操作时,如果未设置指针位置。默认读取文件的位置指针会从文件头移到文件尾,所以读取一次后无法重复读取。
读取文件
f.read(size),size是可选项目,指定字符串长度。size未指定或者为负数,会读取整个文件。当文件大小是当前机器内存两倍时,会出错。如果到了文件末尾,会显示空字符串。
注意:是read(),不是readline()。
1 >>> f.read() 2 'zhe shi wenjian.\n' 3 >>> f.read() 4 '' #这两个单引号是空字符串
读取行
f.readline(),注意:返回的每行结尾会自动加换行符'\n',如果到文件末尾就返回空字符串''。
1 >>> f.readline() 2 'wo shi wenjian neirong.\n' 3 >>> f.readline() 4 'zhe shi di er hang\n' 5 >>> f.readline() 6 '' 7 8 #循环遍历文件对象,来读取第一行。 9 >>> for line in f: 10 ... print(line, end='') 11 ... 12 wo shi wenjian neirong.
13 zhe shi di er hang
如果你想把文件中的所有行读到一个列表中,你也可以使用 list(f) 或者 f.readlines()
写文件
f.write(string)方法将 string 的内容写入文件,并返回写入字符的长度:
>>> f.write('This is a test\n')
15
想要写入其他非字符串内容,首先要将它转换为字符串:
>>> value = ('the answer', 42)
>>> s = str(value)
>>> f.write(s)
18
文件对象的指针操作
f.tell()方法返回一个整数 显示当前指针位置
f.seek(offset,from_what)方法设置设置指针位置。
form_what是起始位置,值为 0 表示自文件起始处开始,1 表示自当前文件指针位置开始,2 表示自文件末尾开始。
1 >> f = open('workfile', 'rb+') 2 >>> f.write(b'0123456789abcdef') 3 16 4 >>> f.seek(5) 5 5 6 >>> f.read(1) 7 b'5' 8 >>> f.seek(-3, 2) 9 13 10 >>> f.read(1) 11 b'd'
可以操作本文本件,但注意一个字符串是3个字节。指针是按字节走的,不是3的倍数显示会出错。
注意:文本中同时包含中文和ascii时,无论是字节还是字符串操作指针,产生乱码比较麻烦。
例如:以下就是产生了不是3的倍数的字节,需要修改bytes字节数据来修复。操作bytes类型的字符,用切片方法切掉坏数据
>>> b
b'abcdefg,\x8d\xe9\x9d\xa2\xe4\xba\x86,\x80\xe4\xb8\x8b\xe5\x9c\xa8\xe5\x89\x8d\xe9\x9d\xa2\xe5\x8a\xa0\xe4\xb8\x80\xe4\xb8\x8b,,try,try12345678abcdef-------hehe'
>>> b[:4]
b'abcd'
>>> b=b[:8]+b[10:]
>>> c.decode('utf-8')
'下在前面加一下,,try,try12345678abcdef-------hehe'
>>>
以下是详细的文件操作例子:
1 >>> f = open('bin_file','wb') #以字节的写模式创建文件对象 2 >>> f.write(b'我是文件内容') #只能是ASCII字符 3 File "<stdin>", line 1 4 SyntaxError: bytes can only contain ASCII literal characters. 5 >>> f.write(b'wo shi wenjian neirong')#只能是ASCII字符 6 22 #一共写了22号字节 7 >>> f.close() 8 >>> 9 (env) hehe@ubuntu:~/tmp/file_object_test$ more bin_file 10 #ascii字节写入的文件,在命令行可以用文本本件方式打开 11 wo shi wenjian neirong 12 >>> f = open('bin_file')#ascii字节写入的文件,用文件对象可以用文本本件方式打开 13 >>> f.read() 14 'wo shi wenjian neirong' 15 >>> f.close() 16 >>> f = open('bin_file','rb')#ascii字节写入的文件,用文件对象可以用字节本件方式打开 17 >>> f.read() 18 b'wo shi wenjian neirong' 19 >>> f.close() 20 >>> f = open('bin_file','wb')#创建以字节写的方式的文件对象 21 >>> f.write(b'我是内容')#写操作时,只能接收字节参数,使用字符串参数会出错 22 File "<stdin>", line 1 23 SyntaxError: bytes can only contain ASCII literal characters. 24 >>> f.write('我是内容'.encode('utf-8'))#把字符串编码成字节就可以写入 25 12 26 >>> f.close() 27 (env) hehe@ubuntu:~/tmp/file_object_test$ more bin_file #命令行下,可以直接以文本方式打开 28 我是内容 29 >>> f = open('bin_file','r')#在交互模式下,可以使用文本模式打开字节写入的中文字符串 30 >>> f.read() 31 '我是内容' 32 >>> f.close() 33 >>> f = open('bin_file','rb') 34 >>> f.read()#每4个符号("\xb9")是一个字节,每3个字节是一个中文。 35 b'\xe6\x88\x91\xe6\x98\xaf\xe5\x86\x85\xe5\xae\xb9' 36 >>> f.tell() 37 12 38 >>> f.seek(0)#因为读取文件的时候指针已经去了文件末尾,所以需要移动它到开头 39 0 40 >>> f.read().decode('utf-8')#用字节模式打开文件,查看中文字符需要解码。 41 '我是内容' 42 >>> f.seek(0) 43 0 44 >>> f.seek(1) 45 1 46 >>> f.read()#往后移动了一个字节所以 \xe6没显示 47 b'\x88\x91\xe6\x98\xaf\xe5\x86\x85\xe5\xae\xb9' 48 >>> f.seek(1) 49 1 50 >>> info=f.read() 51 >>> info.decode('utf-8')#移动一个节字是不行的,3个字节是一个中文, 52 Traceback (most recent call last): 53 File "<stdin>", line 1, in <module> 54 UnicodeDecodeError: 'utf-8' codec can't decode byte 0x88 in position 0: invalid start byte 55 >>> f.seek(3) 56 3 57 >>> info=f.read() 58 >>> info.decode('utf-8')#以下结果正好少了一个字 59 '是内容' 60 >>>
根据python3官方手册 原创内容,如需转载,请标明出处!