python学习第6天----文件操作

1.文件操作

         python中通过open()函数打开一个文件,获取到文件句柄,然后通过文件句柄就可进行各种操作(句柄就相当于一个变量),文件句柄是一个可迭代对象

         打开文件的操作有:r,w,a,r+,w+,a+,rb,wb,ab,r+b,w+b,a+b;默认使用的是r

1)只读操作

英雄.txt
惩戒之箭 九尾妖狐 远古巫灵
f = open("英雄",mode="r",encoding="gbk")  #mode表示打开文件的模式,encoding为文件的编码方式(即操作文件的编码方式为什么)
s = f.read()
f.close()  #关闭文件句柄
print(s)
输出:
惩戒之箭 九尾妖狐 远古巫灵
View Code
注:如果文件不和当前程序在同一个目录下,需要使用绝对路径或者相对路径
    相对路径:相对于当前程序所在的文件夹(写程序时使用相对路径)
    f = open("../../practice/file.txt",mode="r",encoding="utf-8")
    绝对路径:从磁盘根目录寻找;或从互联网上的一个绝对路径

2)只写操作(w):如果文件不存在,则创建

 #往文件中写入内容,会把之前的内容清空

f = open("游戏",mode="w",encoding="utf-8")
f.write("英雄联盟")
f.flush()       #是一个刷新管道(好的习惯)
f.close()
View Code

3)追加模式(a)

 #在原来文件的基础上追加内容:追加时不换行,直接追加到原来文件内容末尾

f = open("游戏",mode="a",encoding="utf-8")
f.write("QQ飞车")
f.flush()
f.close()
View Code

4)从文件中读取字节(rb),即读出来的文件内容为字节;带b表示输入输出的都是字节,非文本文件

f = open("游戏",mode="rb")    #读取的内容直接就是字节
s = f.read()
print(s)
f.close()
输出:
b'xe8x8bxb1xe9x9bx84xe8x81x94xe7x9bx9fQQxe9xa3x9exe8xbdxa6'
View Code

#需要将读出来的字节文件,进行解码,才能看到正常内容

f = open("游戏",mode="rb")
s = f.read()
print(s.decode("utf-8"))
f.close()
输出:
英雄联盟QQ飞车
View Code

5)以字节的形式,将内容写入文件(wb)

 #写入文件时,需要先对写入的内容进行编码;同样会清空原来内容

f = open("游戏",mode="wb")
f.write("天涯明月刀".encode("utf-8"))
f.flush()
f.close()
文件内容:
天涯明月刀
View Code

注:w,r适用于文本的处理;wb,rb处理的是非文本文件(如视频、音频等)

6)追加二进制的形式添加(ab)

f = open("游戏",mode="ab")
f.write("剑侠情缘".encode("utf-8"))
f.flush()
f.close()
文件显示:
天涯明月刀剑侠情缘
View Code

7)读写(r+) 模式:默认情况下,光标在文件的开头,先对后写没有问题,但是先写后读会覆盖最初的内容(r+模式必须先读后写)

f = open("游戏",mode="r+",encoding="utf-8")
print(f.read())
f.write("剑侠情缘")
f.flush()
f.close()
输出:
天涯明月刀
英雄联盟
跑跑卡丁车
文件内容:
天涯明月刀
英雄联盟
跑跑卡丁车剑侠情缘
View Code

8)写读(w+)模式:带w的操作都会情况全赖的内容。(w+平常不用)

#通过w+写入文件内容后,需要先通过seek函数将光标移动到文件开头,再读取文件内容

f = open("游戏",mode="w+",encoding="utf-8")
f.write("剑侠情缘")
f.seek(0)
print(f.read)
f.close()
View Code

2.光标

1)seek(n)表示将光标移动到n的位置(n代表字节),如果是utf-8的中文部分要为3的倍数,即对于utf-8的编码,seek(3)表示移动一个字

文件内容:
剑侠情缘英雄联盟

f = open("游戏",mode="r+",encoding="utf-8")
f.seek(3)
print(f.read())
输出:
侠情缘英雄联盟
View Code

①光标移动到开头:seek(0)

②光标移动到末尾:seek(0,2)  seek的第二个参数表示从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾

注:在r+模式下,如果读取了内容,不论读取多少内容,光标显示的是多少,再写入或者操作文件的时候都是再结尾进行的操作

2)

#read中写入数字,表示读取几个字符(如果在r+模式下读取了内容后,再写内容,都会写入到文件末尾)

f = open("游戏",mode="r+",encoding="utf-8")
s = f.read(3)       #读取3个字
print(s)
输出:
剑侠情
View Code

#在r+模式下,如果开头就进行写操作,会将内容写入到文件开头覆盖

f = open("游戏",mode="r+",encoding="utf-8")
f.write("LOL")
文件内容:
LOL侠情缘
View Code
结论:r+模式下,在没有任何操作之前进行写,在开头写;如果读取了一些内容再写,写入到最好

注: read(3) 表示读取3个字 ;  seek(6)表示移动6个字节,utf-8下为2个字

3).查看光标位置:tell()

3.文件的修改

         先将源文件打开,读取出源文件的内容,在将源文件内容修改,写入到新的文件中,然后将源文件删除,再将新文件重命名为源文件名

1)补充:打开文件方式

①f = open("a.txt",mode="r+",encoding="utf-8")

②with open ("a.txt",mode="r+",encoding="utf-8") as f

两种方式都可打开文件,但是第一种方式,打开文件后需要手动关闭文件,第二种方式是自动关闭文件

2)修改如下文件中的“英雄联盟”为“LOL”

文件内容:
剑侠情缘
英雄联盟
跑跑卡丁车



with open("游戏",mode="r",encoding="utf-8") as f1,open("游戏_副本",mode="w",encoding="utf-8") as f2:
    s = f1.read()
    s_new = s.replace("英雄联盟","LOL")
    f2.write(s_new)
os.remove("游戏")
os.rename("游戏_副本","游戏")
文件内容:
剑侠情缘
LOL
跑跑卡丁车
View Code

4.读取文件

1)循环读取文件每一行(文件也是一个可迭代对象)

with open("游戏",mode="r",encoding="utf-8") as f1:
    for line in f1:            #相当于每次循环执行一次readline
        print(line)
输出:
剑侠情缘
LOL
跑跑卡丁车
=====》
with open("游戏",mode="r",encoding="utf-8") as f1:
lst = f1.readlines()
for line in lst:
View Code

2)读取文件的一行(readline)

with open("游戏",mode="r",encoding="utf-8") as f1:
    s= f1.readline()
    print(s)
输出:
剑侠情缘
View Code

3)对于大文件,修改问价的方式(循环读取文件每一行内容,再进行替换)

with open("游戏",mode="r",encoding="utf-8") as f1,
        open("游戏_副本",mode="w",encoding="utf-8") as f2:
    for line in f1:
        s_new = line.replace("LOL","英雄联盟")
        f2.write(s_new)
View Code

注:: readline()结尾, 注意每次读取出来的数据都会有⼀ 个 所以. 需要我们使⽤strip()⽅法来去掉 或者空格

  readlines()是将文件内容全部读出来,然后返回到一个列表效率最低;

  for循环遍历文件句柄,相当于是readline()读取文件,将文件内容一行一行读取出来;

  read()读取出 的内容是整个文本

5.练习

1)有如下文件啊a1.txt,里面的内容为

------------------------------------------------------------------------------
轻轻的我走了
正如我轻轻的来
我轻轻的招手
作别西天的云彩
---------------------------------------------------------------------------

1)将源文件内容全部读出来并打印

with open("a1.txt",mode="r",encoding="GBK") as f:
    s = f.read()
    print(s)
View Code

②将源文件后面追加一行内容:作者徐志摩,再别康桥

f = open("a1.txt",mode="a",encoding="GBK")
f.write("作者徐志摩,再别康桥")
f.flush()
f.close()
View Code

③将源文件全部读出来,并在后面添加一行内容:作者徐志摩,再别康桥

f = open("a1.txt",mode="r+",encoding="GBK")
f.read()
f.write("作者徐志摩,再别康桥!!!")
f.flush()
f.close()
View Code

④将源文件全部清空,换成下面内容

--------------------------------------------
悄悄的我走了
正如我悄悄的来
我挥一挥衣袖
不带走一片云彩
--------------------------------------------
f = open("a1.txt",mode="w+",encoding="GBK")
f.write('''悄悄的我走了
正如我悄悄的来
我挥一挥衣袖
不带走一片云彩
''')
f.flush()
f.close()
View Code

⑤将源文件内容全部读出来,并在“作别西天的云彩”前加一行“哈哈哈哈”,然后将跟该之后的新内容,写入到一个新文件a2.txt

import os
with open("a1.txt",mode="r",encoding="GBK") as f1, 
    open("a2.txt",mode="w",encoding="GBK") as f2:
    s = f1.read()
    s_new = s.replace("作别西天的云彩","哈哈哈哈
作别西天的云彩")
    f2.write(s_new)
os.remove("a1.txt")
os.replace("a2.txt","a1.txt")
View Code
修改后文件内容如下:
轻轻的我走了
正如我轻轻的来
我轻轻的招手
哈哈哈哈
作别西天的云彩

2)文件内容a.txt 如下

序号	部门	人数	平均年龄	备注
1	python	30	26	单生狗
2	linux	26	30	没对象
3	运维	20	21	女生多
①通过代码:将其构建成如下数据类型:
[{'序号':'1', '部门':'python', '认数':'30', '平均年龄':'26','备注':'单身狗'},。。。]
f = open("a1.txt",mode="r",encoding="GBK")
line = f.readline()      #读出第一行
lst = line.split()      #切割出字典的key
result_list = []
#从文件第一行继续往下读取
for lin in f:
    ll = lin.split()   #i前儿个出字典的value
    dic = {}
    for i in range(len(ll)):        #拿到字典value的索引
        dic[lst[i]] = ll[i]
    result_list.append(dic)   #将每一个字典,添加到列表中
print(result_list)
输出:
[{'部门': 'python', '人数': '30', '备注': '单生狗', '平均年龄': '26', '序号': '1'}, {'部门': 'linux', '人数': '26', '备注': '没对象', '平均年龄': '30', '序号': '2'}, {'部门': '运维', '人数': '20', '备注': '女生多', '平均年龄': '21', '序号': '3'}]
View Code
补充:对于打开文件的方式,【with open() as f】虽然可以自动打开和关闭一个文件,凡是不如【f.open()、f.close()】靠谱,因为如果使用with的打开文件的过程中,程序出现了异常等,那么获取到的资源就得不到释放
原文地址:https://www.cnblogs.com/piaolaipiaoqu/p/13839413.html