Python基础知识—文件管理
1、读写文件
1)创建文件
f = open("new_file.py", "w") # 创建并打开
f.write("some text...") # 在文件里面写东西
f.close() # 关闭
- 文件保存的位置:保存在脚本的当前目录之下,与你运行脚本保持同级目录之下
- 害怕
f.close()
忘记写的话,python中提供了另一种打开文件的方式。这个方式把打开和关闭嵌入到了一个with
架构中。除了使用with模式,还可以使用writelines()
写入数据,当传入的数据时,将数据打包成像列表一样再掺入,列表中的每个元素就是一行记录,数据会分行来写
with open("new_file.py", "w") as f:
f.writelines(["some text for file2...\n", "2nd line\n"])
Tips: 在列表中,每个元素最后都最好写一个\n
来表示换行,不然读出时会造成数据的粘附
2)读文件
f = open("new_file.py", "r")
print(f.read())
f.close()
some text for file2...
2nd line
- 与写文件不同的是,读文件的是
r
,而写文件是w
- 同样,如果你记录的是一个列表,你想按行记录列表中的值时,可以使用
writelines()
,那么在读文件的时候,也可以使用readlines()
直接读出一个列表!
with open("new_file2.txt", "r") as f:
print(f.readlines())
['some text for file2...\n', '2nd line\n']
- 在如今的时代,数据一般都是非常大的,而如果一次性读这么大的文件,这个文件的大小很可能已经超过了你的内存大小。故而,我们需要使用一行一行读取文件,取代一次性读取文件,
readline()
函数就可以做到这一点。
tip: readline()
不是readlines()
,注意区分
with open("new_file2.txt", "r") as f:
while True:
line = f.readline()
print(line)
if not line: # 如果line为空,则跳出循环
break
3)文件编码,中文乱码
不同的版本,不同的电脑,可能使用了不同的文件编码,这时就可能出现中文乱码。
- 常见的文件编码有: “utf-8”、“gbk”、“gb2321”
- 下面的"chinese.txt"模仿使用gbk编码,选择写模式的时候为
wb
,就是使得文件保存为binary
形式,取代默认的text
形式,所以在读代码的时候,也加上了一个b
,为rb
,但运行的时候还是会爆出一段乱码,因为python不识别这段编码后的文本
with open("chinese.txt", "wb") as f:
f.write("这是中文的,this is Chinese".encode("gbk"))
with open("chinese.txt", "wb") as f:
print(f.read())
b'\xd5\xe2\xca\xc7\xd6\xd0\xce\xc4\xb5\xc4\xa3\xacthis is Chinese'
- 假设不使用
rb
,使用r
来读文本,它会报错
with open("chinese.txt", "r") as f:
print(f.read())
- 这时,我们首先需要确定文本是哪一种文件编码,然后在读文件的时候,需要传入一个
encoding
的参数,表示用这一种编码来读,这样就可以顺利解决中文乱码的问题
with open("chinese.txt", "r", encoding="gbk") as f: #注意:这里也是r!!!而不是rb
print(f.read())
这是中文的,this is Chinese
4)更多读写模式
mode | 含义 |
w | (创建)写文本 |
r | 读文本,文件不存在会报错 |
a | 在文本最后添加 |
wb | 写二进制binary |
rb | 读二进制binary |
ab | 添加二进制 |
w+ | 又可以读又可以(创建)写 |
r+ | 又可以读又可以写,文件不存在会报错 |
a+ | 可读写,在文本最后添加 |
x | 创建 |
举例:
with open("new_file.txt", "r") as f:
print(f.read())
with open("new_file.txt", "r+") as f:
f.write("text has been replaced")
f.seek(0) # 将开始读的位置从写入的最后位置调到开头
print(f.read())
some text...
text has been replaced
with open("new_file.txt", "a+") as f:
print(f.read()) # 这里读出的是空行,为什么呢?请见下面的tip
f.write("\nadd new line")
f.seek(0) # 将开始读的位置从写入的最后位置调到开头
print(f.read())
some text...
add new line
tip:为什么第一个print(f.read())输出的是空行呢?
因为a+:打开一个文件用于读写,如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式,如果该文件不存在,创建新文件用于读写
2、文件目录管理
- 文件目录操作:
-
os.getcwd()
:获取当前目录 -
os.listdir()
:获取当前目录中文件列表 -
os.makedirs()
:创建一个文件夹 -
os.path.exists()
:检测文件是否真实存在
- 文件管理系统:
-
os.removedirs()
:删除文件夹 -
shutil.rmtree()
:删除文件,但不可恢复 -
os.rename()
:重新命名
- 文件目录多重检验:
-
os.path.isfile()
: os.path.exists()
os.path.isdir()
os.path.basename()
os.path.dirname()
os.path.split()
1)os库
os库中包含了很多操作文件和目录的函数
2)文件目录操作
- 获取当前目录,获取当前目录的文件列表
import os
print("当前目录:", os.getcwd())
print("当前目录的文件列表:", os.listdir())
当前目录: /Users/mr.wei/Desktop/code/python_study_code/test
当前目录的文件列表: ['new_file.txt', 'chinese.txt', 'test.file.py']
- 创建文件夹、检测文件/文件夹是否真实存在
os.makedirs("project", exist_ok=True)
print(os.path.exits("project"))
# 其中,exit_ok=True的意思是检测到这个目录存在也是被允许的
# 就像本来我要创建这个文件夹,它已经存在了,那我的工作就没有意义了,所以我默认是不允许它存在的,但是设置了exist_ok=True,那么就可以允许它的存在!
3)文件管理系统
- 为用户创建文件夹
if os.path.exists("user/Mr.wei"):
print("user exist")
else:
os.makedirs("user/Mr.wei")
print("user created")
print(os.listdir("user"))
user created
['Mr.wei']
- 删除用户文件夹
if os.path.exitsts("user/Mr.wei")
os.removedirs("user/Mr.wei")
print("user removed")
else:
os.makedirs("user no exist")
user removed
- 但当删除文件夹时,文件夹不为空,就会报错。
os.makedirs("/user/Mr.wei", exist_ok=True)
with open("user/Mr.wei/a.txt", "w") as f:
f.write("nothing")
os.removedirs("user/Mr.wei")
报错!
- 这时,有另一个库
shutil
,值得注意的是,用它来删除文件夹时,要当心,因为删除了就真的没了
import shutil
shutil.rmtree("user/Mr.wei")
print(os.listdir("user"))
[]
- 为文件重命名:
os.makedirs("user/Mr.wei", exist_ok=True)
os.rename("user/Mr.wei", "user/wgt")
print(os.listdir("user"))
['wgt']
4)文件目录多种检验(os.path
)
import os
os.makedirs("user/Mr.wei", exist_ok=True)
with open("user/Mr.wei/a.txt", "w") as f:
f.write("nothing")
print(os.path.isfile("user/Mr.wei/a.txt")) # 判断它是否为一个文件
print(os.path.exists("user/Mr.wei/a.txt")) # 判断它是否存在
print(os.path.isdir("user/Mr.wei/a.txt")) # 判断它是否是一个目录
print(os.path.isdir("user/Mr.wei"))
True
True
False
True
- 一般情况下,文件的路径
path
都是传参进来的,比如一个功能:告诉一个文件目录,为这个文件创建一个副本(将文件新复制一份eg:file.txt
的副本为file(1).txt
):
- First:先拿到文件名os.path.basename
- Second :拿到文件夹名os.path.dirname
- Third: 将副本重命名
- Fourth:将目录重新组合os.path.join
import os
def copy(path):
file_name = os.path.basename(path)
dir_name = os.path.dirname(path)
new_filename = "new_" + file_name
return os.path.join(dir_name, new_filename)
print(copy("user/Mr.wei/a.txt"))
user/Mr.wei/new_a.txt
- 更方便的办法拿到文件夹名+文件名:
def copy(path):
dir_name, filename = os.path.split(path)
new_filename = "new_" + filename
return os.path.join(dir_name, new_filename)
print(copy("user/Mr.wei/a.txt"))
user/Mr.wei/new_a.txt