该章节将使用Python在硬盘上创建、读取和保存文件
一、文件与文件路径
1、Windows中使用\以及macOS和Linux中使用/
使用pathlib模块中的Path()函数进行文件名和目录的拼接,返回文件路径字符串
from pathlib import Path
print(Path("spam","bacon","egg"))
>> spam\bacon\egg
由于Path(r"spam\eggs")在Windows中表示两个单独目录,但在macOS和Linux中表示一个名为spam\eggs的目录或文件,因此,今后再写文件路径时使用正斜杠/
2、使用/连接路径
使用/组合Path对象和字符串,应注意前两个值中有一个必须是Path对象。原因在于Python从左往右求值/运算符,并求值为一个Path对象,因此只有当前两个值有一个为Path对象时整个表达式才能求值为Path对象。
好处在于无论代码在哪种操作系统上,pathlib模块都可以重新使用/正确地连接路径从而解决问题。
print(Path("spam") / "bacon" / "eggs")
>> spam\bacon\eggs
3、当前工作目录
使用Path.cwd()函数可以取得当前工作路径的字符串,并可以利用os.chdir()改变它
from pathlib import Path
import os
print(Path.cwd())
os.chdir('E:\\test')
print(Path.cwd())
>> C:\Users\ROG\Desktop\pythonProject
>> E:\test
注意chdir()中是\\
4、主目录
使用Path.home()查看
print(Path.home())
>> C:\Users\ROG
主目录位于一个特定位置,具体取决于操作系统
- 在Windows中,主目录位于C:\Users下
- 在macOS中,主目录位于/Users下
- 在Linux中,主目录位于/home下
5、绝对路径与相对路径
绝对路径:从根目录开始
相对路径:相对于程序的当前工作目录
相对路径开始处的.\是可选的。例如,.\spam.txt 和spam.txt 指的是同一个文件。
6、用os.makedirs()创建新目录
如果中间目录不存在,os.makedirs()会将其创建出来
也可通过Path对象先创建目录,再调用mkdir()方法
os.makedirs("C:\\Users\\ROG\\Desktop\\test.py")
Path(r"E:\Users\ROG\Desktop").mkdir()
7、处理绝对路径和相对路径
1)从相对路径中获取绝对路径
将Path.cwd() / 放在相对Path对象的前边,因为相对路径几乎总是指相对于当前工作目录的路径
print(Path.cwd() / Path("my/relative/path"))
>> C:\Users\ROG\Desktop\pythonProject\my\relative\path
2) os.path模块提供的一些有用函数
- 将相对路径转换成绝对路径:os.path.abspath(path)
- 判断是否是绝对路径:os.path.isabs(path)
- 返回从开始路径到path路径的相对路径:os.path.relpath(path,start)
print(os.path.abspath("."))
>> C:\Users\ROG\Desktop\pythonProject
print(os.path.isabs(Path.cwd()))
print(os.path.isabs("."))
>> True
>> False
print(os.path.relpath(r"C:\Config",Path.cwd()))
>> ..\..\..\..\Config
8、取得文件路径的各部分
驱动:drive 锚点:anchor 父文件夹:parent 文件名:name 主干名:stem 后缀名:suffix
从文件路径中提取每个属性
p = Path("C:/Users/AI/spam.txt")
p.drive ---> C:
p.anchor ---> C:/
p.parent ---> WindowsPath("C:\Users\AI") 返回为另一个Path对象
p.name ---> spam.txt
p.stem ---> spam
p.suffix ---> .txt
parents属性求值为一组Path对象
p = Path("C:/Users/Al/AppData/Local/Programs/Python/Python36-32/Lib/site")
for index,path in enumerate(p.parents):
print("parents[%s] = %s"%(index,path))
os.path.split(calcFilePath)获取一个路径的目录名称和基本名称的元组,calcFilePath即可为Path对象,也可为路径字符串
os.sep作为string类中的split方法里的参数用以按路径中分隔斜杠分割路径,返回每个文件夹的字符串列表。在Windows中分隔斜杠为\,在macOS和Linux中为/,用不对分割不了(如第三个print)
p = Path(r"C:\Users\Al\AppData\Local\Programs\Python\Python36-32\Lib\site")
print(os.path.split(p))
print(os.path.split(r"C:\Users\Al\AppData\Local\Programs\Python\Python36-32\Lib\site"))
print("C:/Users/Al/AppData/Local/Programs/Python/Python36-32/Lib/site".split(os.sep))
print(r"C:\Users\Al\AppData\Local\Programs\Python\Python36-32\Lib\site".split(os.sep))
print("C:\\Users\\Al\\AppData\\Local\\Programs\\Python\\Python36-32\\Lib\\site".split(os.sep))
9、查看文件大小和文件夹内容
os.path.getsize(path):返回path参数中文件的字节数
os.listdir(path):返回文件名字符串的列表,包含path参数中的每个文件
print(os.path.getsize(r"D:\steam\steam.exe"))
print(os.listdir(r"D:\java"))
目录下所有文件的总字节数求法:
allDirs = os.listdir(r"D:\java")
totalSize = 0
for dir in allDirs:
totalSize += os.path.getsize(os.path.join(r"D:\java",dir))
print(totalSize)
10、使用通配符模式修改文件列表
*:多个任意字符
?:任意单个字符
Path对象使用glob()方法根据“通配符模式”列出文件夹内容 ,再配合list()展现出来。glob()方法返回一个生成器对象。
p = Path(r"D:\attack on titan2")
print(list(p.glob("*.exe")))
print(list(p.glob("TB03_v2.0.5.0-?.bin")))
这里不会返回TB03_v2.0.5.0-10.bin,因为?只会匹配一个字符
for循环遍历glob()返回的生成器对象
p = Path(r"D:\attack on titan2")
for i in p.glob("*.bin"):
print(i)
11、检查路径的有效性
p = Path("xxx")
p.exists():该路径是否存在,返回True
p.is_file():该路径存在且为一个文件,返回True
p.is_dir():该路径存在且为一个目录,返回True
二、文件读写过程
读写文件有3 个步骤:
- 调用open()函数,返回一个File 对象。
- 调用File 对象的read()或write()方法。
- 调用File 对象的close()方法,关闭该文件。
1、用open()函数打开文件
open()函数中可以传递Path对象,也可传递字符串,函数将返回File对象
testFile = open(Path.cwd() / 'test.txt')
helloFile = open(".\\hello.txt")
2、读取文件内容
使用File对象的read()方法时,会将整个文件内容当成一个长字符串返回
使用readlines()方法时,从该文件取得一个字符串的列表,列表中的每个字符串就是文本中的每一行。
当前hello.txt内容
读全文:
helloFile = open(".\\hello.txt")
helloContent = helloFile.read()
print(helloContent)
分行读取:
helloFile = open(".\\hello.txt")
helloContentLine = helloFile.readlines()
print(helloContentLine)
>> ['large moustache. Mrs Dursley was thin and blonde and had nearly twice the usual amount\n', 'of neck, which came in very useful as she spent so much of her time craning over garden\n', 'fences,spying on the neighbours. The Dursleys had a small son called Dudley and in their\n', 'opinion there was no finer boy anywhere.\n', '\n']
注意,每次读完后读取指针会在文章最末尾,因此想要再次读取文章内容时,要重置指针到文章开头:
helloFile.seek(0)
3、写入文件
向open()方法中传递第二个参数,默认是读模式"r":
1)写模式:"w" 2)添加模式: "a"
如果open()打开的文件名不存在,则两个模式均会创建一个新的空文件,在读取或写入文件后,调用close()方法,然后才能再次打开该文件
helloFile = open(".\\hello.txt","w")
helloFile.write("Hello World !")
helloFile.close()
helloFile = open(".\\hello.txt","a")
helloFile.write("add contents.")
helloFile.close()
注意,write()方法不会在字符串的末尾自动添加换行字符,必须自己添加该字符。
三、用shelve模块保存变量
shelve 模块可以将Python 程序中的变量保存到二进制的shelf 文件中。这样,程序就可以从硬盘中恢复变量的数据。
shelfFile = shelve.open("test")
cats = ['cat1', 'cat2', 'cat3']
shelfFile['cats'] = cats #将cats列表保存在shelfFile中,并作为键"cats"关联的值
shelfFile.close()
这3个文件包含了存储在shelf中的数据
shelf值有keys()和values()方法,返回shelf中键和值的类似列表值,不是真列表,因此要使用list()进行类型转换来取得列表形式
print(list(shelfFile.keys()))
print(list(shelfFile.values()))
>> ['cats']
>> [['cat1', 'cat2', 'cat3']]
创建文件时,如果需要在文本编辑器中读取它们,纯文本就非常有用。但是,如果想要保存Python 程序中的数据,那就使用shelve 模块。