python基础知识之文件的读取操作

文件的操作方法主要就是“打开文件”、“读取文件(修改文件)”、“关闭文件”

打开文件要使用open()函数,()内涉及的参数在初期阶段我们只需要知道三个参数即可

首先是文件名,类型是字符串,要包含路径,如果要打开的文件和当前文件在同一个目录下则可以省略路径(相对路径).

然后是打开文件的模式,格式是:mode=’模式’, 这里的”mode=”可以省略,直接写模式即可,具体的模式如下

r
只读。文件的指针将会放在文件的开头。这是默认模式。
rb
只读的二进制格式。文件指针将会放在文件的开头。
r+
读写。文件指针将会放在文件的开头。
rb+
读写的二进制格式。文件指针将会放在文件的开头。
w
只写。如果该文件已存在则打开文件,清空文件内容。如果该文件不存在,则创建新文件。
wb
只写的二进制格式。如果该文件已存在则打开文件,清空文件内容。如果该文件不存在,创建新文件。
w+
写读。如果该文件已存在则打开文件,清空文件内容。如果该文件不存在,创建新文件。
wb+
写读的二进制格式。如果该文件已存在则打开文件,清空文件内容。如果该文件不存在,创建新文件。
a
追加写。如果该文件存在,文件指针将会放在文件的结尾。新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab
追加写的二进制格式。如果该文件存在,文件指针将会放在文件的结尾。新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+
追加写读。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+
追加写读的二进制格式。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

第三个参数是文件的编码(非二进制格式时使用),编码的设置必须与要打开的文件的编码一致,否则会报错,也就是说源文件是用什么编码写入的,你打开时就得用什么编码打开。

#我们来举一个例子,要实现的操作是打开文件名为“test”的文件,原文件编码为utf-8,文件中只有一句话:
#十步杀一人,千里不留行。
file = open('test','r',encoding='gbk')#如果用gbk编码则会报错,大意是gbk编码无法解码(文件打开的过程实际就是
#解码的过程)
#这里说明以下,open函数返回的结果是一个文件对象,所以要用一个变量接收一下(file),这样我们就可以方便地使用这个
#对象的方法了,比如file.read(),file.write,file.flush()等等
content = file.read()#read()是文件对象的一个方法,作用是读取指定的字符数,如果未指定则默认读取所有内容
print(content)
file.close()
---------------------------------------------------------------------------

UnicodeDecodeError                        Traceback (most recent call last)

<ipython-input-78-bb879f008680> in <module>()
      4 #这里说明以下,open函数返回的结果是一个文件对象,所以要用一个变量接收一下(file),这样我们就可以方便地使用这个
      5 #对象的方法了,比如file.read(),file.write,file.flush()等等
----> 6 content = file.read()#read()是文件对象的一个方法,作用是读取指定的字符数,如果未指定则默认读取所有内容
      7 print(content)
      8 file.close()


UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 4: illegal multibyte sequence
#这时我们将编码方式改为utf-8
file = open('test')#因为我们只是要读取下文件,所以模式为r,而默认模式为r,可以省略不写,又因为我是linux系统,
#默认就是utf-8编码,所以编码也可以省略不写 
content2 = file.read(3)#这里一定要注意,read()括号内是字符数,不是字节数
#print(asdasd)
print('指定3个字符时读取结果为:',content2)
file.close()
指定3个字符时读取结果为: 十步杀
#接下来我们创建一个二进制格式的文件
with open('二进制','wb') as file: #我们之前使用的打开文件的方式比较麻烦,因为必须要在结束时写关闭文件的语句,
#这里是一种简便的方法,使用这种方法的好处是不用写关闭文件的语句,with 和as是关键字,记住格式即可
    file.write('十步杀一人,千里不留行'.encode('utf8'))
#这里说明以下为什么在写入文件时要在字符串后面加上.encode(utf8)的方法,因为我们创建的文件是二进制格式的(wb),
#这样我们在写入内容时就必须指定该内容的编码,实际上计算机把任何内容写入存储器时都是用某种编码的方式写入的,
#因为计算机只能识别二进制编码,而此时我们创建的是二进制文件内容,那么在写入“十步杀一人,千里不留行”这句话
#时就要指定它的编码方式,因为计算机并不能识别这句话,计算机只认识二进制,所以我们指定其为utf8的编码方式
#形象地解释:open函数相当于打开了一种通道,平时打开时都是用某种编码的方式打开的,所以我们在写入内容时不必管
#它以什么编码进入通道的(因为在open函数里面就已经指定了编码方式,而当open函数使用二进制格式打开时(就是带b
#的模式),这个通道就没有指定编码方式,通道里面只有二进制,所以此时往通道里面放#内容的话就需要指定一种编码方式。
#然后我们来读取一下上面创建的名字为“二进制”的这个文件
with open('二进制','rb') as file:
    print('不指定解码方式时的结果:',file.read())#如果我们在读取时不指定解码方式,那么输出的值就是下面这种奇
                                                #怪的东西(实际上它是用16进制表示的二进制)
    file.seek(0) #因为之前读取过文件,所以文件指针在末尾位置,seek方法作用是把文件指针设置在指定位置(你可以简单地理解为光标)
    content = file.read()
    print('指定解码方式后的结果:',content.decode('utf-8'))#此时我们指定了文件的解码方式为utf-8,那些16进制就变成了我们能理解的字符串了
不指定解码方式时的结果: b'\xe5\x8d\x81\xe6\xad\xa5\xe6\x9d\x80\xe4\xb8\x80\xe4\xba\xba\xef\xbc\x8c\xe5\x8d\x83\xe9\x87\x8c\xe4\xb8\x8d\xe7\x95\x99\xe8\xa1\x8c'
指定解码方式后的结果: 十步杀一人,千里不留行
#其他的在读取时可能用到的方法:
with open('libai') as file:
    print(file.readline())#readline()读取一行,如果里面添加了参数n,则会读取n个字符(我觉得这是个bug,貌似没什么卵用)
    print(file.readlines())#readlines()读取所有内容(注意指针位置),结果返回一个列表,元素由每一行组成。
    print(file.tell())#tell()会输出当前指针的位置,注意,该位置是以字节来表示的,不是字符(utf-8编码下一个
    #汉字为3个字节,一共144个汉字(包括标点符号)就是432个字节,在算上换行符,差不多就是输出的结果440了
赵客缦胡缨,吴钩霜雪明。银鞍照白马,飒沓如流星。

['十步杀一人,千里不留行。事了拂衣去,深藏身与名。\n', '闲过信陵饮,脱剑膝前横。将炙啖朱亥,持觞劝侯嬴。\n', '三杯吐然诺,五岳倒为轻。眼花耳热后,意气素霓生。\n', '救赵挥金锤,邯郸先震惊。千秋二壮士,烜赫大梁城。  \n', '纵死侠骨香,不惭世上英。谁能书阁下,白首太玄经。\n']
440

使用readlines()并不是一个好方法,因为是一次性将文件都读取到内存中,如果文件较大时则造成内存溢出,实际中使用下面的方法,系统会自动生成一个迭代器,用迭代的方法把需要的数据取出来。

with open('libai') as f:
    for i in f: #这里的i实际就是迭代后的每一行,用for循环的方式从文件对象中取出来,取一行读一行,节省内存
        print(i)
赵客缦胡缨,吴钩霜雪明。银鞍照白马,飒沓如流星。

十步杀一人,千里不留行。事了拂衣去,深藏身与名。

闲过信陵饮,脱剑膝前横。将炙啖朱亥,持觞劝侯嬴。

三杯吐然诺,五岳倒为轻。眼花耳热后,意气素霓生。

救赵挥金锤,邯郸先震惊。千秋二壮士,烜赫大梁城。  

纵死侠骨香,不惭世上英。谁能书阁下,白首太玄经。

猜你喜欢

转载自blog.csdn.net/Grim777/article/details/81501785