文件操作

1. r模式

1.1 全部读取

我们先来建一个文件,放到D盘根目录下,文件内容如图

我们需要把它的内容读出来,怎么操作呢,来看一段代码

1 f = open("d:\元旦.txt", encoding="utf-8", mode="r")
2 content = f.read()
3 print(content)
4 f.close()

输出

大海啊好多水
兔子啊四条腿
你是谁
你从哪里来
你要到哪里去

我们详细看一下代码,第一行的意思是调用操作系统的open函数获取文件句柄,句柄顾名思义就是像勺子的柄一样,用句柄来对文件的内容进行操作。获取句柄需要指定三个参数:文件路径,编码方式和打开模式。第二行f.read()是通过句柄获取文件的全部内容赋值给变量content,然后打印输出,最后关闭文件句柄,文件句柄会占用资源,使用完成之后要记得关闭。总结一下,文件读取的步骤:

1. 打开文件,产生句柄(参数:路径,编码方式,打开模式)
2. 对文件句柄进行操作
3. 关闭文件

上面的read()里面可以传入参数n,表示一次读取n个字符

1 f = open("d:\元旦.txt", encoding="utf-8", mode="r")
2 content = f.read(5)   # 按字符读取
3 print(content)
4 f.close()

输出结果

大海啊好多

1.2 读取一行

一行一行地读取(readline)

1 f = open("d:\元旦.txt", encoding="utf-8", mode="r")
2 content1 = f.readline()
3 content2 = f.readline()
4 content3 = f.readline()
5 print(content1)
6 print(content2)
7 print(content3)
8 f.close()

执行结果

大海啊好多水

兔子啊四条腿

你是谁

可以看到readline是从当前位置往后读一行,这里每行中间空一行是因为python的print函数会自动换行,再加上文件里卖弄的换行符就有两行了。readline()也可以加上参数n,表示读取n个字符,如readline(3)表示读取3个字符

1.3 读取所有行(readlines)

readlines(0表示读取所有行,以列表的形式返回结果,列表的每个元素表示一行

1 f = open("d:\元旦.txt", encoding="utf-8", mode="r")
2 content = f.readlines()
3 print(content)
4 f.close()

执行结果

['大海啊好多水\n', '兔子啊四条腿\n', '你是谁\n', '你从哪里来\n', '你要到哪里去\n', '\n', '\n']

 

1.4 循环读取(for)

这里大家可能就有一个问题:如果我要逐行读取整个文件,怎么做呢?用for循环!来看代码:

1 f = open("d:\元旦.txt", encoding="utf-8", mode="r")
2 for line in f:
3     print(line, end="")   # end=""表示将print函数结尾位置默认的换行符改成空字符
4 f.close()

执行结果

大海啊好多水
兔子啊四条腿
你是谁
你从哪里来
你要到哪里去

 

2. rb模式

rb模式操作的是非文字类的文件,图片,视频,音频等

2.1 读取全部(read)

1 f = open("D:\元旦.txt", mode="rb")    # 注意rb模式不能声明编码
2 content = f.read()   # 读取全部
3 print(content)
4 f.close()

执行结果

b'\xe5\xa4\xa7\xe6\xb5\xb7\xe5\x95\x8a\xe5\xa5\xbd\xe5\xa4\x9a\xe6\xb0\xb4\r\n\xe5\x85\x94\xe5\xad\x90\xe5\x95\x8a\xe5\x9b\x9b\xe6\x9d\xa1\xe8\x85\xbf\r\n\xe4\xbd\xa0\xe6\x98\xaf\xe8\xb0\x81\r\n\xe4\xbd\xa0\xe4\xbb\x8e\xe5\x93\xaa\xe9\x87\x8c\xe6\x9d\xa5\r\n\xe4\xbd\xa0\xe8\xa6\x81\xe5\x88\xb0\xe5\x93\xaa\xe9\x87\x8c\xe5\x8e\xbb\r\n\r\n\r\n'

可以看到rb模式读取的是一大段bytes类型的数据, read()也可以传入参数n, 表示读取n个字节

2.2 读取一行(readline)

1 f = open("D:\元旦.txt", mode="rb")
2 content1 = f.readline()
3 content2 = f.readline()
4 content3 = f.readline()
5 print(content1)
6 print(content2)
7 print(content3)
8 f.close()

执行结果

b'\xe5\xa4\xa7\xe6\xb5\xb7\xe5\x95\x8a\xe5\xa5\xbd\xe5\xa4\x9a\xe6\xb0\xb4\r\n'
b'\xe5\x85\x94\xe5\xad\x90\xe5\x95\x8a\xe5\x9b\x9b\xe6\x9d\xa1\xe8\x85\xbf\r\n'
b'\xe4\xbd\xa0\xe6\x98\xaf\xe8\xb0\x81\r\n'

rb模式下readline()也可以传入参数n,表示读取n个字节

2.3 读取所有行(readlines)

1 f = open("D:\元旦.txt", mode="rb")
2 content = f.readlines()
3 print(content)
4 f.close()

返回一个列表。元素是bytes类型的数据

[b'\xe5\xa4\xa7\xe6\xb5\xb7\xe5\x95\x8a\xe5\xa5\xbd\xe5\xa4\x9a\xe6\xb0\xb4\r\n', b'\xe5\x85\x94\xe5\xad\x90\xe5\x95\x8a\xe5\x9b\x9b\xe6\x9d\xa1\xe8\x85\xbf\r\n', b'\xe4\xbd\xa0\xe6\x98\xaf\xe8\xb0\x81\r\n', b'\xe4\xbd\xa0\xe4\xbb\x8e\xe5\x93\xaa\xe9\x87\x8c\xe6\x9d\xa5\r\n', b'\xe4\xbd\xa0\xe8\xa6\x81\xe5\x88\xb0\xe5\x93\xaa\xe9\x87\x8c\xe5\x8e\xbb\r\n', b'\r\n', b'\r\n']

 

2.4 循环读取所有行(for)

1 f = open("D:\元旦.txt", mode="rb")
2 for i in f:
3     print(i)
4 f.close()

输出

b'\xe5\xa4\xa7\xe6\xb5\xb7\xe5\x95\x8a\xe5\xa5\xbd\xe5\xa4\x9a\xe6\xb0\xb4\r\n'
b'\xe5\x85\x94\xe5\xad\x90\xe5\x95\x8a\xe5\x9b\x9b\xe6\x9d\xa1\xe8\x85\xbf\r\n'
b'\xe4\xbd\xa0\xe6\x98\xaf\xe8\xb0\x81\r\n'
b'\xe4\xbd\xa0\xe4\xbb\x8e\xe5\x93\xaa\xe9\x87\x8c\xe6\x9d\xa5\r\n'
b'\xe4\xbd\xa0\xe8\xa6\x81\xe5\x88\xb0\xe5\x93\xaa\xe9\x87\x8c\xe5\x8e\xbb'

 

3. r+模式

先读后写(后追加)

1 f1 = open('D:\元旦.txt', encoding='utf-8', mode='r+')
2 content1 = f1.read()
3 print(content1)
4 f1.write('\n天生我材必有用')
5 content2 = f1.read()
6 print(content2)
7 f1.close()

执行结果

大海啊好多水
兔子啊四条腿
你是谁
你从哪里来
你要到哪里去

没有打印写入的内容,为什么呢?因为写入内容后光标已经移到文件末尾了,再读取就都不到内容了,打开文件看看改了没

大海啊好多水
兔子啊四条腿
你是谁
你从哪里来
你要到哪里去
天生我材必有用

小结

(1)read()读取全部;read(n)读取n个字符或字节;readline()读取一行

(2)r模式按字符读取;rb模式按字节读取

4. w模式

(1)没有文件创建文件写入;有文件清空原文件内容写入新内容

(2)注意w模式必须是以字符串的形式写入

文件file1内容

让我们荡起双桨
小船儿推开波浪

执行代码

1 f1 = open("file1", encoding="utf-8", mode="w")
2 f1.write("666")    # 会写入三个666
3 f1.close()

结果

666

新建一个文件写入

1 f1 = open("明月.txt", encoding="utf-8", mode="w")
2 f1.write("海上升明月\n天涯共此时")    # 会写入三个666
3 f1.close()

执行结果

海上升明月
天涯共此时

如果打开一个句柄后不关闭,再在当前文件上创建一个句柄对其进行写入操作,可以吗?一般不可以(有时候会出错)

1 f1 = open("明月.txt", encoding="utf-8", mode="w")
2 f1.write(”666“)     # 这里必须是字符串,不能是数字
3 f1.write("abc")
4 
5 f2 = open("明月.txt", encoding="utf-8", mode="w")
6 f2.write("哈哈哈")

文件内容

海上升明月
天涯共此时

执行结果

哈哈哈

 

5. wb模式

下面来看一个实例,运用rb和wb实现图片的复制

1 f1 = open("妹子.jpg", mode="rb")
2 content = f1.read()   # 获取内容
3 f1.close()   # 关闭文件句柄
4 f2 = open("妹子1.bmp", mode="wb")   
5 f2.write(content)             # 将内容写入新文件
6 f2.close()

视频也一样可以

 

6. w+模式

1 f1 = open("明月.txt", encoding="utf-8", mode="w+")
2 f1.write("天涯")
3 f1.write("明月")
4 f1.write("")
5 f1.seek(0)    # 把光标移到最前面,括号里参数以字节为单位
6 content = f1.read()
7 print(content)

执行结果

天涯明月刀

如果把seek里面的参数改为2就会报错,因为中文在utf-8里占3个字节,截断2个字节会出错

7. a模式

追加:没有文件时创建新文件写入,有文件时把内容追加到末尾

1 f1 = open("明月.txt", encoding="utf-8", mode="a")
2 f1.write("天地入杯")
3 f1.close()

执行结果

天涯明月刀天地入杯

8. a+模式

追加和读

1 f1 = open("明月.txt", encoding="utf-8", mode="a+")
2 f1.write("谁的歌声轻轻淌")
3 f1.seek(0)
4 data = f1.read()
5 print(data)

执行结果

天涯明月刀天地入杯谁的歌声轻轻淌

 

9. 其他操作方法

(1) flush强制刷新到硬盘
(2)readable判断是否可读
(3)writable判断是否可写

(4)seek(n)  把光标引动到n个字节的位置;tell()返回当前光标的位置

(5)truncate  截断,truncate() 可以在r+, w+模式下截取原文件。只能从头截取,不能调整光标截取一部分。

1 f1 = open("明月.txt", encoding="utf-8", mode="w+")
2 f1.write("天涯明月刀")
3 f1.truncate(9)   # 按字节截取,如果参数不是3的倍数会乱码
4 f1.close()

执行结果

天涯明

 

with open

 好处:

(1)自动关闭文件句柄
(2)可以一个语句打开多个文件句柄

用法:

1 with open("file1", encoding="utf-8", mode="r+") as f1,\
2     open("file2", encoding="utf-8", mode="r+") as f2:
3     data1 = f1.read()
4     data2 = f2.read()
5     print(data1)
6     print(data2)

执行结果

海上升明月
天涯共此时
哈喽

 

文件的修改

 

文件修改步骤:
1. 以读的模式打开原文件,产生文件句柄f1
2. 以写的模式打开新文件,产生文件句柄f2
3. 读取原文件,将原文件的内容改写成新文件内容写入新文件
4. 删除原文件
5. 把新文件重命名为原文件

1 import os
2 with open("log", encoding="utf-8", mode="r") as f1,\
3     open("log.bak", encoding="utf-8", mode="w") as f2:
4     for line in f1:
5         old_line = line
6         new_line = old_line.replace("hello", "hi")
7         f2.write(new_line)
8 os.remove("log")  # 删除原文件
9 os.rename("log.bak", "log")  # 将新文件命名为原文件

 

posted @ 2018-12-27 20:31  乘月归  阅读(241)  评论(0编辑  收藏  举报