python:17 文件操作

文件操作

  • 文件操作的作用
  • 文件的基本操作
    • 打开
    • 读写
    • 关闭
  • 文件备份
  • 文件和文件夹的操作

1 文件操作的作用

思考:什么是文件?

下图中都是属于文件

思考: 文件操作包含什么?

答: 打开、关闭、读、写、复制….

思考: 文件操作的的作用是什么?

答: 读取内容,写入内容、备份内容….

总结: 文件操作的作用就是把一些内容(数据)存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力

  • 文件操作步骤:

    • 打开
    文件对象 = open(file,访问模式)
    • 操作

    文件对象.read()         # 写长度表示读出对应长度内容,不写长度表示读取所有
    文件对象.readlines()    # 已行为单位读取,每行出现的是列表中的元素
    文件对象.readline()     # 一次读一行
    文件对象.write()
    • seek():改变文件指针

    • 关闭

    文件对象.close()
  • 主访问模式

    • w:写,文件不存在则新建该文件
    • r:读,文件不存在则报错
    • a:追加
  • 文件和文件夹操作

    • 重命名: os.rename()
    • 获取当前目录: os.getcwd()
    • 获取目录列表: os.listdir()

2 文件的基本操作

2.1 文件操作步骤

  1. 打开文件
  2. 读写等操作
  3. 关闭文件

注意:可以只打开和关闭文件,不进行任何读写操作

2.1.1 打开

在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下:

open(name,mode)

name: 是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。

mode: 设置打开文件的模式(访问模式): 只读、写入、追加等

2.1.2 文件对象方法

2.1.1.1 打开文件模式

不同模式打开文件的完全列表:

  • 下面模式中但凡带 b 的都是二进制文件
  • 但凡带 + 都是可读可写模式
  • 文件指针相当于文件中光标的位置
模式 描述
t 文本模式 (默认)。
x 写模式,新建一个文件,如果该文件已存在则会报错。
b 二进制模式。
+ 打开一个文件进行更新(可读可写)。
U 通用换行模式(不推荐)。
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。
w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

文件打开模式有很多,但是我们实际用到的就只有六种。

我们总结一下主要用到的是下面六种。

注意:

访问模式参数可以省略,如果省略则表示访问模式为 r

2.1.1.2 快速体验

写入:

# w 模式写入文件内容,如果该文件没有那么就创建一个 file
f = open("test.txt","w")

# 写入内容
f.write('aaa')

# 关闭文件句柄
f.close()
# 由于当前目录下没有 test.txt 这里就创建了一个
[15:23:02 root@dev py-demo]#ll test.txt 
-rw-r--r-- 1 root root 3 Dec 27 15:23 test.txt
[15:23:08 root@dev py-demo]#cat test.txt 
aaa

2.1.2 主访问模式

2.1.2.1 r 只读模式

读取报错测试:

# r 读取,如果文件不存在就报错,不支持写入操作因为表示只读
f = open('tes1t.txt','r')

# 调用 redi 函数,读取文件内容返回并 print 打印
print(f.read())

# 关闭文件句柄
f.close()
# 没有 tes1t.txt 文件所以报错
[15:29:50 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
Traceback (most recent call last):
  File "/root/py-demo/day-1/test.py", line 9, in <module>
    f = open('tes1t.txt','r')
FileNotFoundError: [Errno 2] No such file or directory: 'tes1t.txt'

读取不报错测试:

# r 读取,如果文件不存在就报错,不支持写入操作因为表示只读
f = open('test.txt','r')

# 调用 redi 函数,读取文件内容返回并 print 打印
print(f.read())

# 关闭文件句柄
f.close()
[15:30:54 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
adasdasdasdada

2.1.2.2 w 只写模式

# 只写,如果文件不存在,新建文件;执行写入,会覆盖原有内容
f = open('1.txt','w')
f.write("1231231")
f.close()
[15:34:55 root@dev py-demo]#cat 1.txt 
1231231
# 只写,如果文件不存在,新建文件;执行写入,会覆盖原有内容
f = open('1.txt','w')

# 写入内容为 aaaaa ,会将上面代码写入的 1231231 内容覆盖
f.write("aaaaa")
f.close()
[15:36:27 root@dev py-demo]#cat 1.txt 
aaaaa

2.1.2.3 a 追加模式

# a 追加,如果文件不存在,新建文件,不会覆盖文件原有内容
f = open('2.txt','a')
f.write('abc')
f.close()
[15:39:10 root@dev py-demo]#cat 2.txt 
abc

这里我又重新编写代码,追加 123 到 2.txt 中可以看到文件内容并没有覆盖而是在当前 abc 后追加了 123

# a 追加,如果文件不存在,新建文件,不会覆盖文件原有内容
f = open('2.txt','a')
f.write('123')
f.close()
[15:39:48 root@dev py-demo]#cat 2.txt 
abc123

2.1.3 读

1.为做实验先创建一个文件,如下内容

[16:13:52 root@dev py-demo]#cat test.txt 
aaaaaaa
bbbbbbb
ccccccc
ddddddd
eeeeeee
  • read()
文件对象.read(num)

num 表示要从文件中读取的数据的长度 (单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。

读取所有:

f = open('test.txt','r')

# read 不写参数表示读取文件所有内容
print(f.read())

f.close()
[16:14:48 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
aaaaaaa
bbbbbbb
ccccccc
ddddddd
eeeeeee

指定 num 读取字节长度

f = open('test.txt','r')

# read 不写参数表示读取文件所有内容
print(f.read(10))

f.close()
# 输出的时候有换行占位符 \n 占一个字节,所看到只有 9 个字母输出
[16:15:47 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
aaaaaaa
bb
  • readlines()

readlines 可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。

f = open('test.txt','r')

# 返回列表
print(f.readlines())
f.close() 
[16:25:11 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
['aaaaaaa\n', 'bbbbbbb\n', 'ccccccc\n', 'ddddddd\n', 'eeeeeee\n']
  • readline()

readline() 一次读取一行内容

f = open('test.txt')

content = f.readline()

print(f'第一行:{content}')

content = f.readline()
print(f'第二行:{content}')

f.close()
[09:42:50 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
第一行:aaaaaaa

第二行:bbbbbbb

2.2 代码测试不同的访问模式

如下测试内容:

  • r+:可读可写模式
  • W+:可读可写模式

用于测试不同访问模式之间的具体区别,并测试不同的访问模式对我们光标是否有影响

2.2.1 r+ 模式

f = open('test1.txt','r+')

f.close()
# 由于当前没有test1 这个文件所以报错
[10:24:11 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
Traceback (most recent call last):
  File "/root/py-demo/day-1/test.py", line 7, in <module>
    f = open('test1.txt','r+')
FileNotFoundError: [Errno 2] No such file or directory: 'test1.txt'
# 当前有 test 文件不会报错
f = open('test.txt','r+')

f.close()
[09:46:38 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py

测试:文件指针对文件数据的影响

# 当前 test 文件内容
[10:26:32 root@dev py-demo]#cat test.txt 
aaaaaaa
bbbbbbb
ccccccc
ddddddd
eeeeeee
f = open('test.txt','r+')

con =  f.read()

print(con)

f.close()
[10:31:07 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
aaaaaaa
bbbbbbb
ccccccc
ddddddd
eeeeeee

特点:

  • r+ 遵循主访问模式r的特点,如果没有文件则会报错
  • r+ 所有的 r 访问模式文件指针都是在文件开头的位置并向后读取

2.2.2 w+ 模式

w+:打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。

f = open('test1.txt','w+')

f.close()
# 可以看到会自动创建一个 test1 文件
[10:35:28 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
[10:36:08 root@dev py-demo]#ll test1.txt 
-rw-r--r-- 1 root root 0 Dec 28 10:36 test1.txt
# 通过 w+ 读取 test 文件
f = open('test.txt','w+')

con = f.read()

print(con)

f.close()
# 可以看到当前 test 文件内容已经没有了,因为即原有内容会被删除。

[10:36:10 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
[10:39:01 root@dev py-demo]#cat test.txt 

特点:

  • w+ 遵循主访问模式 w 的特点,所以当没有该文件的时候就会自动创建一个新的文件
  • w+ 读取文件,文件指针在开头并会将源文件所有内容覆盖掉,即原有内容会被删除。

2.2.3 a+ 模式

打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。

f = open('test111.txt','a+')

f.close()
# test111 文件并不存在,但是执行代码并没有报错,而且新建了一个 test111 文件
[10:42:38 root@dev py-demo]#ll test111.txt 
-rw-r--r-- 1 root root 0 Dec 28 10:42 test111.txt

test.txt 文件中写入数据

[10:44:21 root@dev py-demo]#echo "11111" > test.txt 
[10:44:44 root@dev py-demo]#cat test.txt 
11111
# 通过 a+ 模式读取 test数据
f = open('test.txt','a+')

print(f.read())

f.close()
# 没有读取到数据,因为 a+ 的文件指针是从文件末尾开始
[10:44:46 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py

特点:

  • a+ 如果该文件不存在,创建新文件用于读写。
  • a+ 文件指针将会放在文件的结尾,无法读取数据

2.2.4 seek 函数

作用:用来移动文件指针,因为文件指针出现的位置会影响读取到的文件数据

语法如下:

文件对象.seek(偏移量,起始位置)

起始位置:

  • 0:文件开头
  • 1:当前位置
  • 2:文件结尾

因为我们在上面的模式测试中知道,r 模式的文件指针是在文件开头,那么我想读取中间第 10 个字符该怎么办呢,这时候就需要 seek 函数;比如还有 a 模式默认文件指针是在文件结尾,所以读取不到内容也可以通过 seek ,以此类推

2.2.4.1 测试 r 模式

示例1:

1 查看 test.txt 文件当前内容

[10:46:12 root@dev py-demo]#cat test.txt 
11111
f = open('test.txt','r')

# 将文件指针偏移 3 个,默认为文件开头向右偏移
f.seek(3)

print(f.read())
# 可以看到将后面两个字符读取
[10:54:12 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
11

示例2:

将文件指针放到结尾通过 r 读取:

直接报错

f = open('test.txt','r+')

# 文件指针起始位置放到结尾读取
f.seek(2,2)

print(f.read())
f.close() 
# 直接报错
[10:59:58 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
Traceback (most recent call last):
  File "/root/py-demo/day-1/test.py", line 3, in <module>
    f.seek(2,2)
io.UnsupportedOperation: can't do nonzero end-relative seeks

2.2.4.2 测试 a 模式

因为我们都知道 a 模式默认的文件指针是在文件结尾,所以需要通过 seek 函数将文件指针设置为起始,从而实现读取文件内容

f = open('test.txt','a+')

# 将文件指针偏移设置为 0 ,并且从文件开头设置为起始
f.seek(0,0)

con = f.read()

print(con)

f.close()
[11:15:10 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
11111

3 文件备份

需求:

用户输入当前目录下任意文件名,程序完成对该文件的备份功能(备份文件名为 xx [备份文件名为 xx[备份]后缀,例如:test[备份].txt)

其实所谓的备份就是先打开文件将源文件内容写入到目标文件中,然后再关闭文件

3.1 步骤

  1. 接收用户输入的文件名
  2. 规划备份文件名
  3. 备份文件写入数据
    • 打开文件
    • 写入数据
    • 关闭文件

3.2 代码实现

1 接收用户输入目标文件名

# 接收用户输入数据
old_name = input('输入需要备份的文件名:')

2 规划备份文件

  • 提取目标文件后缀
  • 组织备份的文件名,xx[备份]后缀
# 2.提取文件后缀,找到用户输入的文件名中的 . 名字和后缀进行分离,文件最后面的 . 就是文件后缀
# 2.1 rfind ()方法返回字符串最后一次出现的位置的下标,从右侧寻找
index = old_name.rfind('.')

# 2.2 新名字 = 原名字 + [备份] + 后缀
# 原名字就是字符串中的一部分子串 -- 切片[开始:结束:步长]
# index 是通过 rfind 函数取出的最后一个下标位置
# 拼接得到新的文件名
new_name = old_name[:index] + '[备份]' + old_name[index:]
print(new_name)

3 备份文件写入数据

  • 打开源文件和备份文件
  • 将源文件写入备份文件
  • 关闭文件
'''
3 备份写入数据
    打开源文件和备份文件
    将源文件写入备份文件
    关闭文件
'''
# 打开文件
# rb,wb 模式,主要是涉及到后期的图片或者其他非文本文件内容的写入
old_f = open(old_name,'rb')
new_f = open(new_name,'wb')

# 源数据读取文件,如果不确定目标文件大写,就通过循环写入,当不在读取到数据就终止循环
while True:
    # 每次读取 1024 个字节
    con = old_f.read(1024)

    # len(con) 判断是否为 0 ,如果为 0 表示读取完成并退出
    if len(con) == 0:
        break

    # 将读取出来的数据写入到 new_f 中
    new_f.write(con)

old_f.close()
new_f.close()

3.2.1 代码总览验证

'''
1. 接收用户输入的文件名
2. 规划备份文件名
3. 备份文件写入数据
'''

# 1.接收用户输入数据
old_name = input('输入需要备份的文件名:')

# 2.提取文件后缀,找到用户输入的文件名中的 . 名字和后缀进行分离,文件最后面的 . 就是文件后缀
# 2.1 rfind ()方法返回字符串最后一次出现的位置的下标,从右侧寻找
index = old_name.rfind('.')

'''
2.2 新名字 = 原名字 + [备份] + 后缀
    原名字就是字符串中的一部分子串 -- 切片[开始:结束:步长]
    index 是通过 rfind 函数取出的最后一个下标位置
    拼接得到新的文件名
'''
new_name = old_name[:index] + '[备份]' + old_name[index:]
print(new_name)

'''
3 备份写入数据
    打开源文件和备份文件
    将源文件写入备份文件
    关闭文件
'''
# 打开文件
# rb,wb 模式,主要是涉及到后期的图片或者其他非文本文件内容的写入
old_f = open(old_name,'rb')
new_f = open(new_name,'wb')

# 源数据读取文件,如果不确定目标文件大写,就通过循环写入,当不在读取到数据就终止循环
while True:
    # 每次读取 1024 个字节
    con = old_f.read(1024)

    # len(con) 判断是否为 0 ,如果为 0 表示读取完成并退出
    if len(con) == 0:
        break

    # 将读取出来的数据写入到 new_f 中
    new_f.write(con)

old_f.close()
new_f.close()

验证:

# 创建一个test.txt 文件并写入内容
[10:50:40 root@dev py-demo]#echo '1231232132132131212313dddddddddddddddddddddddddddddddddddddddd' > test.txt 

# 执行程序
[10:51:32 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
输入需要备份的文件名:test.txt
test[备份].txt

# 查看结果
[10:51:53 root@dev py-demo]#cat test\[备份\].txt 
1231232132132131212313dddddddddddddddddddddddddddddddddddddddd

3.3 思考

如果用户输入 .txt ,这是一个无效文件,程序如何更改才能限制只有有效的文件名才能备份?

如下代码,添加条件判断即可:

'''
1. 接收用户输入的文件名
2. 规划备份文件名
3. 备份文件写入数据
'''

# 1.接收用户输入数据
old_name = input('输入需要备份的文件名:')

# 2.提取文件后缀,找到用户输入的文件名中的 . 名字和后缀进行分离,文件最后面的 . 就是文件后缀
# 2.1 rfind ()方法返回字符串最后一次出现的位置的下标,从右侧寻找
index = old_name.rfind('.')

# 有效文件才备份,比如 .txt 就为无效文件就不再备份
# 将文件名最后一个 . 的坐标获取,然后再通过 if 判断并拿到 [index:] 最后的文件后缀给 postfix 变量
if index > 0 :
    postfix = old_name[index:]
else:
    print('文件格式不正确!')
# 
'''
2.2 新名字 = 原名字 + [备份] + 后缀
    原名字就是字符串中的一部分子串 -- 切片[开始:结束:步长]
    index 是通过 rfind 函数取出的最后一个下标位置
    拼接得到新的文件名
'''
# 将上面拿到的 postfix 变量重新添加到文件后缀中
new_name = old_name[:index] + '[备份]' + postfix
print(new_name)

'''
3 备份写入数据
    打开源文件和备份文件
    将源文件写入备份文件
    关闭文件
'''
# 打开文件
# rb,wb 模式,主要是涉及到后期的图片或者其他非文本文件内容的写入
old_f = open(old_name,'rb')
new_f = open(new_name,'wb')

# 源数据读取文件,如果不确定目标文件大写,就通过循环写入,当不在读取到数据就终止循环
while True:
    # 每次读取 1024 个字节
    con = old_f.read(1024)

    # len(con) 判断是否为 0 ,如果为 0 表示读取完成并退出
    if len(con) == 0:
        break

    # 将读取出来的数据写入到 new_f 中
    new_f.write(con)

old_f.close()
new_f.close()
# 创建 1.txt
[15:45:20 root@dev py-demo]#touch 1.txt

# 输入正确的文件
[15:45:25 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
输入需要备份的文件名:1.txt
1[备份].txt

# 输入无效文件名直接报错退出程序
[15:45:30 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
输入需要备份的文件名:.txt
文件格式不正确!

4 文件和文件夹的操作

Python中文件和文件夹的操作要借助 os 模块里面的相关功能,具体步骤如下:

1 导入 os 模块

import os

2 使用 os 模块相关功能

os.函数名()

4.1 文件重命名

os.rename(目标文件名,新文件名)
"""
1.导入 os 模块
2.使用模块功能
"""

import os

# 需要改名的文件
file = '1.txt'

os.rename(file,"2.txt")
[15:46:54 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
[15:52:52 root@dev py-demo]#ls 2.txt 

4.2 删除文件

os.remove(文件名)
"""
1.导入 os 模块
2.使用模块功能
"""

import os

# 当前文件路径
file = './2.txt'

os.remove(file)
[15:52:54 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
[15:53:47 root@dev py-demo]#ls 2.txt
ls: cannot access '2.txt': No such file or directory

4.3 创建文件夹

os.mkdir(文件夹名称)
import os 

os.mkdir("./test")
[15:53:53 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
[15:57:43 root@dev py-demo]#ls test/

4.4 删除文件夹

os.rmdir(文件名)
import os 

os.rmdir("./test")
[15:57:46 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
[15:58:54 root@dev py-demo]#ls test
ls: cannot access 'test': No such file or directory

4.5 获取当前目录

os.getcwg()
import os

# 返回 str 数据类型
print(os.getcwd())
# 获取当前路径
[16:00:29 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
/root/py-demo

4.6 改变默认目录

os.chdir(目录)
# 创建一个 aa 文件夹
[16:00:49 root@dev py-demo]#mkdir aa
import os

# 切换操作目录为当前路径下的 aa
os.chdir("./aa")

# 在 aa 目录中创建 bb
os.mkdir("bb")
[16:12:21 root@dev py-demo]#ls aa/
bb

4.7 获取目录列表

import os

# 指定获取当前目录下的 aa 文件夹
print(os.listdir('./aa'))
[16:12:21 root@dev py-demo]#/bin/python3 /root/py-demo/day-1/test.py
bb
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇