Python连载(0015): 文件操作

1. 前言

我们平时操作文本文件的时候,基本上都是按照如下步骤:

  • 创建新文件或者打开已有文件
  • 读或者修改文件内容
  • 保存文件并关闭

用Python操作文件的基本步骤也是类似的,Python提供了文件创建、打开、读、写、保存、关闭等接口函数供用户使用。今天老王就来整理一下这些接口函数的使用方法。

2. 操作模式

在打开文件的时候,需要指定对文件的操作模式。比如,以只读模式打开或者以写入模式打开等等。Python支持多种操作模式,功能如下:

  • r模式(只读模式)

    打开文件后,只能读取文件内容,不能修改。

  • w模式(写入模式)

    如果要操作的文件不存在,那么会创建一个新文件

    如果要操作的文件存在,那么新写入的内容会覆盖文件中原有的内容

  • a模式(追加模式)

    以该模式打开文件后,新写入的内容会被添加到文件末尾不会覆盖文件中的原有内容

    如果文件不存在,那么会创建一个新文件

  • w+模式(写读模式)

    这个模式老王没怎么用到过,它在w模式的基础上,添加了读权限。也就是说,以w+模式打开文件之后,你向文件写了一部分内容,然后在不用重新打开文件的情况下,你接着就可以把刚才写的内容读出来。

  • r+模式(读写模式)

    能读能写,写入的内容都被添加到文件最后。

  • a+模式(追加读模式)

    文件打开之后,光标就会在文件末尾,写入的数据全部添加到文件最后。

3. 创建文件

需求:

  • D:创建一个名为test.txt文本文件。
  • 向文件中写入一些内容
  • 保存并关闭文件。
# 以写模式打开文件,鉴于当前D盘下没有test.txt文件,所以它会创建该文件。
f = open("D:/test.txt", "w")
# 也可以写成: f = open(file = "D:/test.txt", mode = "w")

# 向文件中写入一行信息
f.write("这是第1行文本。\n")
f.write("这是第2行文本。\n")
f.write("这是第3行文本。\n")
f.write("这是第4行文本。\n")

# 关闭文件,同时会对文件进行保存。
f.close()

4. 只读模式操作文件

# 打开已经存在的文件
f = open(file = "D:/test.txt", mode = "r")

# 读1行,并输出
text = f.readline()
print(text)
print("-"*10)	# 输出一串字符进行分隔

# 读取剩下的所有内容
text = f.read()
print(text)

# 关闭文件
f.close()

image-20210130172044675

注:观察上面的运行结果,我们发现在这是第一行文本。----------之间多了一个空行,这是为什么?f.readline()的时候,它读取的这一行文本中本来就带了一个换行符,而使用print()输出时,该函数会默认在输出的内容后面再加一个换行符,所以就导致多了一个空行。如果想要规避这个现象,可以将print(text)改成print(test, end="")。改完之后,程序运行结果如下:

image-20210130172542609

5. 追加模式

在之前创建的D:/test.txt中,追加一行本文。

# 以追加模式打开文件
f = open("D:/test.txt", "a")

# 向文件中追加写入一行信息
f.write("这是一行追加的文本。\n")

# 关闭文件,同时会对文件进行保存。
f.close()

执行完成后,D:/test.txt文件内容如下:

image-20210130172914157

6. r+模式

假设当前D:/test.txt文件的内容如下:

这是第1行文本。
这是第2行文本。
这是第3行文本。
这是第4行文本。

然后执行如下代码:

# 以r+模式打开文件
f = open("D:/test.txt", "r+")

# 读取1行
text = f.readline()
print(text)

# 写入1行信息
f.write("这是为了验证r+模式写入的文本。")

# 关闭并保存文件
f.close()

执行结果如下:

image-20210130174033822

image-20210130174050845

从上面的结果我们可以发现,以r+模式打开文件后,执行读操作时,它是从第一行开始读;执行写操作时,它是将新内容写到文件末尾。

可以这么理解,当打开一个文件后,会有一个读光标写光标,分别对应读操作和写操作的位置。以r+模式打开文件后,读光标位于文件的起始处,而写光标位于文件的末尾。因此,读操作会得到文件的第一行,而写入的内容会添加到文件末尾。

7. 遍历文件

逐行读取文件的所有内容,并输出。

# 打开文件
f = open("D:/test.txt", "r")

# 逐行读取文件
for line in f:
    print(line, end="")
    print("-"*10)

# 关闭文件
f.close()

image-20210130173254460

8. 指定文件编码

在打开文件的时候,可以指定以哪种文件编码格式打开文件,用法如下:

# 以写模式打开文件,指定'utf-8'编码
f = open("D:/test.txt", "w", encoding = "utf-8")

# 向文件中写入一行信息
f.write("这是第1行文本。\n")
f.write("这是第2行文本。\n")
f.write("这是第3行文本。\n")
f.write("这是第4行文本。\n")

# 关闭文件,同时会对文件进行保存。
f.close()

# 打开文件,指定'utf-8'编码
f = open("D:/test.txt", "r", encoding = "utf-8")

# 逐行读取文件
for line in f:
    print(line, end="")
    print("-"*10)

# 关闭文件
f.close()

9. 其他功能

9.1 read()

read()可以一次将整个文件的内容读取出来,放到一个字符串中。这种操作有一个缺点,如果文件非常大时会很耗内存。

# 打开文件,指定'utf-8'编码
f = open("D:/test.txt", "r", encoding = "utf-8")

# 读取全部文件
text = f.read()
print(text, end="")

# 关闭文件
f.close()

image-20210130182909604

9.2 readline()

readline()一次读取文件中的一行,以字符串形式保存。这种操作倒是内存损耗小,但是一次只能处理一行,所以会比较慢。

# 打开文件,指定'utf-8'编码
f = open("D:/test.txt", "r", encoding = "utf-8")

# 读取1行
text = f.readline()
print(text, end="")

# 关闭文件
f.close()

image-20210130183155642

9.3 readlines()

readlines()一次读取整个文件,并保存成一个列表,文件的每一行成为列表的一个元素。

缺点和read()一样,读取大文件的时候耗内存。

# 打开文件,指定'utf-8'编码
f = open("D:/test.txt", "r", encoding = "utf-8")

# 读取所有文本
text = f.readlines()
print(text)

print("-"*10)
print(text[0], end="")
print(text[1], end="")
print(text[2], end="")

# 关闭文件
f.close()

image-20210130183509910

9.4 flush()

代码对文件进行操作,在执行f.close()之前,对文件的修改其实都是在内存中进行的,这时候还没有保存到硬盘上。如果执行f.close()之前停电了,那对文件的修改是无法生效的,再开机之后就会发现文件并没有被修改。

flush()就是主动将内存中对文件的修改写入到硬盘中,避免系统奔溃或者断电时来不及保存。

# 以写模式打开文件
f = open("D:/test.txt", "w")

# 向文件中写入一行信息
f.write("这是第1行文本。\n")
f.flush()	# 刷新硬盘
f.write("这是第2行文本。\n")
f.flush()	# 刷新硬盘
f.write("这是第3行文本。\n")
f.flush()	# 刷新硬盘
f.write("这是第4行文本。\n")

# 关闭文件,同时会对文件进行保存。
f.close()

注:flush()会引入硬盘写入,而硬盘的写入操作比内存要慢N倍,所以频繁flush()会导致程序效率降低。

9.5 seek()

我们知道,在访问文件时,会有一个光标指示当前在操作文件的哪个位置,如果在打开文件后直接将光标移动到指定位置,可以使用seek()

seek()的长度是按照字节算的,而不同的编码方式又导致每个字符所占的字符长度不一样。

恭喜发财四个汉字,在GBK编码下,一个汉字占2个字节,此时seek(4)就能把光标切换到两个字中间。但在utf-8编码下,一个汉字占3个字节,此时seek(4)就只能拿到字的一部分,输出的时候就会报错。

9.6 tell()

tell()用于返回当前光标的位置,也是以字节为单位。

9.7 readable() & writable() & seekable()

readable()用于判定当前是否对文件具有读权限。

writable()用于判定当前是否对文件具有写权限。

seekable()用于判定当前是否对文件具有seek权限。

9.10 name

获取当前文件的文件名。

f = open("D:/test.txt", "r")
print("当前打开的文件是:{}".format(f.name))
f.close()

image-20210130190011944

注意:name后面不要跟一对小括号()

9.11 fileno

返回文件句柄在内核中的索引值,以后做IO多路复用时可以用到。

f = open("D:/test.txt", "r")
print("当前打开的文件是:{}".format(f.fileno))
f.close()

image-20210130190040943

注意:fileno后面不要跟一对小括号()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值