介绍
文件称之为,数据存放的容器,其作用是持久性的存储数据内容。
文件由文件名、扩展名和文件内容组成,其特点为:
- 如果是同级目录下,不允许同名文件存在。
- 有.jpg .avi .doc .xls .html等,一般不同的扩展名,对应着不同的文件格式,而不同的文件格式有着不同的存储约定,从而方便程序处理。
- 文本文件,txt/doc/xls等;二进制文件,图片/视频/音乐等。
基本操作
- 打开
- 读写
- 关闭
打开
利用open函数
open(“文件”,“模式”)
文件:指定文件路径
模式:指的是控制操作模式
模式:
- 参数
r
以只读方式打开文件(默认模式);文件的指针将会放在文件的开头;若文件不存在,会报错。 - 参数
w
以只写方式打开文件;文件的指针将会放在文件的开头,所以对于写入的新内容,会覆盖原写的所以内容;若文件不存在,会自动创建一个新文件。 - 参数
a
以追加方式(只写)打开文件;文件的指针将会放在文件结尾,所以,写入的内容,会新增到文件结尾;若文件不存在,会自动创建一个新文件。 - 参数增加
b
(rb, wb, ab)如果文件是二进制文件,则选择此项。以二进制格式进行操作文件读写,例如、图片、视频、音频等。 - 参数增加
+
(r+, w+, a+, rb+, rw+, ab+) 代表都是以"读写模式"进行打开。比如r+也可以进行文件的写入操作,但不会删除原先的内容,而是逐步覆盖原先的内容;若加上了read()函数操作,那么只会追加写入内容而不会覆盖。
例子:
- r+能直接写入:
# 1.打开文件
# 相对路径,相对于哪一个目录下面的指定文件
f = open("a.txt","r+")
# 2.读写操作
# content = f.read()
# print(content)
f.write("abcdefghijklmn")
# 3.关闭文件
f.close()
输出:
- r+是逐步写入,不会删除原内容:
# 1.打开文件
# 相对路径,相对于哪一个目录下面的指定文件
f = open("a.txt","r+")
# 2.读写操作
# content = f.read()
# print(content)
f.write("123")
# 3.关闭文件
f.close()
输出:
- 加上读函数后,r+是追加写入:
# 1.打开文件
# 相对路径,相对于哪一个目录下面的指定文件
f = open("a.txt","r+")
# 2.读写操作
content = f.read()
print(content)
f.write("666")
# 3.关闭文件
f.close()
输出:
定位
f = open("a.txt","r+")
print(f.tell()) # 查看当前指针位置
f.seek(2) # 指针移到第二个位置
print(f.tell())
print(f.read()) # 读取内容
print(f.tell())
f.close()
文件内容为123456789
输出:
f = open("a.txt","rb")
print(f.tell()) # 查看当前指针位置
f.seek(-2,2) # 指针移到最后,再往前走两位
print(f.tell())
print(f.read()) # 读取内容
print(f.tell())
f.close()
文件内容为123456789
输出:
读
read读取
我们知道read()函数里面什么都不加是默认全部读取,若加上数字,则可设定读取个数:
f = open("a.txt","r")
content = f.read(2)
print(content)
f.close()
文件内容:123456789
输出:
12
readline读取
f = open("a.txt","r")
content = f.readline() # 按行读取
print(content, end='')
content = f.readline() # 按行读取
print(content, end='')
content = f.readline() # 按行读取
print(content, end='')
f.close()
输出:
123
456
789
readlines读取
f = open("a.txt","r")
content = f.readlines() # 多行读取,并归为列表
print(content)
f.close()
输出:
[‘123\n’, ‘456\n’, ‘789’]
利用循环读取
from collections.abc import Iterator
f = open("a.txt", "r")
print(isinstance(f, Iterator)) # 查看是否为迭代器(表明可以动态计算数据)
for i in f:
print(i, end="")
f.close()
输出:
检测文件是否可读
f = open("a.txt", "a")
if f.readable():
for i in f:
print(i, end="")
f.close()
输出不会报错,这样保证了程序不崩溃。
那么我们如何选取方法?
- 一般文件特别大的时候,可以使用readline方法,按行加载,可节省内存但相比于其他两个读取方法,性能较低。
- 其他两个方法,一次性读取文件所有内容,虽然占用内存,但处理性能比较高。
写
f = open("a.txt", 'a')
if f.writable():
print(f.write("abc")) # 返回的是写入内容的字节长度
f.close()
返回值为写入长度,但写入的内容是abc。
关闭
为什么需要关闭?
一是为了释放系统资源,二会立即清空缓冲区的数据内容到磁盘文件。
f.close() 关闭文件
f.flush() 立即清空缓冲区的数据内容到磁盘文件(保存)
其他操作
利用os模块
import os
重命名
os.rename(‘old’, ‘new’) #修改单级 目录/文件 名称
os.renames(‘old’, ‘new’) #修改多级 目录/文件 名称
import os
os.rename('b.txt', 'bb.txt') # txt文件修改
os.rename('up', 'sleep') # 文件夹修改
os.renames('one/one.txt', 'two/two.txt') # 改文件夹名称并改文件名称
删除
os.remove(“文件路径”) # 文件不存在会报错
os.rmdir(path) # 不能递归删除目录,如果文件夹非空,会报错
os.removedirs(path) # 可以递归的删除日录,如果文件夹非空,会报错
import os
os.remove("xx2.ipg")
os.rmdir("one/one2")
os.removedirs("one/one2")
创建文件夹
os.mkdir(“文件夹名称”[,mode]) # 不能递归创建,不能创建多级目录
其中mode指的是设定数字模式权限
目录
os.getcwd() # 获取当前路径
os.chdir(“目标目录”) # 改变默认目录
os.listdir(“./”) # 获取目录内容列表
import os
# 获取当前路径
os.getcwd()
print(os.getcwd())
# 改变默认目录
os.chdir("目标目录")
# 获取目录内容列表
os.listdir("./") # 获取当前所在目录
os.listdir("../") # 获取上一级所在目录
案例
文件复制
要求:将一个文件复制到另一个副本中。
# 1.只读模式,打开要复制的文件
# 追加模式,打开副本文件
source_file = open("a.txt", "r", encoding='utf-8') # utf-8为文件编码格式
dst_file = open("b.txt", "w", encoding='utf-8')
# 2.从源文件中读取内容
# 写入到目标文件中
content = source_file.read()
dst_file.write(content)
# 3.关团源文件和目标文件
source_file.close()
dst_file.close()
文件分类
文件分类,并生成个文件清单,即我们的目标任务为:
# 0. 获取所有的文件名称列表
import os
import shutil
path = "files" # 指定路径
if not os.path.exists(path): # 若不存在则直接退出
exit()
os.chdir(path) # 移动到指定路径下
file_list = os.listdir("./") # 获取当前路径下的所以文件名称
# print(file_list)
# 1.遍历所有的文件(名称)
for file_name in file_list:
# print(file_name)
# 2.分解文件的后缀名
# 2.1 获取最后一个.的索引位置 xx.00.txt
index = file_name.rfind(".")
if index == -1: # 若没有发现.文件,则跳过
continue
# print(index)
# 2.2 根据这个索引位置,当做起始位置,来截取后续的所有字符串内容
extension = file_name[index + 1:]
# print(extension)
# 3.查看一下,是否存在同名的目录
# 4.如果不存在这样的目录->直接创建一个这样名称的目录
if not os.path.exists(extension):
os.mkdir(extension)
# 5,目录存在->移动过去
shutil.move(file_name, extension)
输出:
列表清单
import os
# 通过给定的文件夹,列举出这个文件夹当中,所有的文件,以及文件夹,子文件夹当中的所有文件
def listFiles(dir):
# 1.列举出,当前给定的文件夹下的所有子文件夹,以及子文件
file_list = os.listdir(dir)
# print(file_list)
# 2.针对于列举的列表,进行遍历
for file_name in file_list:
new_fileName = dir + "/" + file_name
# 判定,是否是目录,1istFiles
if os.path.isdir(new_fileName):
print(new_fileName)
listFiles(new_fileName)
else:
# 打印下,文件名称
print("\t"+ file_name)
print("") # 加一个换行
listFiles("files")
输出:
若需要写到文件中保存下来,我们对函数进行一定的修改:
import os
# 通过给定的文件夹,列举出这个文件夹当中,所有的文件,以及文件夹,子文件夹当中的所有文件
def listFilesToTxt(dir, file):
# 1.列举出,当前给定的文件夹下的所有子文件夹,以及子文件
file_list = os.listdir(dir)
# print(file_list)
# 2.针对于列举的列表,进行遍历
for file_name in file_list:
new_fileName = dir + "/" + file_name
# 判定,是否是目录,1istFiles
if os.path.isdir(new_fileName):
# print(new_fileName)
file.write(new_fileName + "\n")
listFilesToTxt(new_fileName, file)
else:
# 打印下,文件名称
# print("\t"+ file_name)
file.write("\t"+ file_name)
# print("") # 加一个换行
file.write("\n")
f = open("list.txt", "a")
listFilesToTxt("files", f)
输出:
list的文件内容为