29. 文件操作
一、数据读写
在程序运行时会生成各种各样的数据,如果数据量少,可以直接将其保存在内存中,计算结束时清空内存并把结果保存到文件中。如果在计算中生成大量的中间数据,则需要把数据写到临时文件中,计算结束时把临时文件删除。
为保存数据,可以用 Python 提供的 open()
函数 打开或新建文件进行文本文件的读写,对于大量的有固定格式的数据,可以用PySide6 提供的以数据流的方式读写文本数据、二进制数据和原生数据的方法和函数,以及对临时文件进行管理和监控的函数,很方便地对数据进行读写和对文件进行管理。
在 PySide6 中,我们可以把文件当作输入输出设备,可以把数据写到设备中,或者从设备中读取数据,从而达到读写数据的目的。我们可以利用 QFile
类调用 QIODevice
类的读写方法 直接进行读写,或者把 QFile
类和 QTextStream
类结合起来,用 文本流(text stream)的方法进行文本数据的读写,还可以把 QFile
类和 QDataStream
类结合进来,用 数据流(data stream)的方法进行二进制数据的读写。
我们可以在终端中使用 pip
安装 PySide6 模块。默认是从国外的主站上下载,因此,我们可能会遇到网络不好的情况导致下载失败。我们可以在 pip
指令后通过 -i
指定国内镜像源下载。
pip install pyside6 -i https://mirrors.aliyun.com/pypi/simple
国内常用的 pip
下载源列表:
- 阿里云 https://mirrors.aliyun.com/pypi/simple
- 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple
- 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple
- 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple
在 PySide6 窗口程序对文件或者文件夹进行操作时,不强制要求必须使用 PySide6 中提供的
QFile
、QDir
等类,也可以使用 Python 内置的文件对象。
1.1、QIODevice抽象类
PySide6 中用于文件读写操作的类是 QFile
,它提供了文件读写的接口函数,可以直接对文件进行读写。QFile
的父类是 QFileDevice
,它提供了文件交互操作的底层功能。再上一级父类是 QIODevice
,它是所有输入/输出设备的基础类。
QIODevice
类是抽象类,是执行读数据和写数据类(如 QFile
、QBuffer
)的基类,它提供读数据和写数据的接口。QIODevice
类在 QtCore
模块中。我们不能直接使用 QIODevice
类进行数据的读写,而是使用子类 QFile
或 QBuffe
r 的继承自 QIODevice
的读写方法来进行数据读写。在一些系统中,将所有的外围设备都当作文件来处理,因此可以读写的类都可以当作设备来处理。
QIODevice
类的常用方法如下:
open(mode:QIODeviceBase.OpenMode) -> bool # 打开设备,成功返回True
isOpen() -> bool # 判断设备是否打开
setOpenMode(openMode:QIODeviceBase.OpenMode) -> None # 打开设备后,重新设置打开模式
close() -> None # 关闭设备
setTextModeEnabled(enabled:bool) -> None # 设置是否是文本模式
getChar(c:bytes) -> bool # 读取一个字符,并存储到c中
putChar(c:str) -> bool # 写入一个字符
ungetChar(c:str) -> None # 将字符重新存储到设备中
peek(length:int) -> QByteArray # 读取指定数量的字节
read(length:int) -> QByteArray # 读取指定数量的字节数据
readLine(length:int) -> QByteArray # 读取一行数据
readData(length:int) -> QObject # 读取数据
readAll() -> QByteArray # 读取全部数据
write(data:Union[QByteArray, byteArray]) -> int # 写入字符串,返回实际写入的字节数量
writeData(data:bytes, length:int) -> int # 写入数据,返回实际写入的字节数量
setCurrentWriteChannel(channel:int) -> None # 设置当前的写入通道
currentWriteChannel() -> int # 获取当前的写入通道
writeChannelCount() -> int # 获取写入数据的通道数量
setCurrentReadChannel(channel:int) -> None # 设置当前的读取通道
currentReadChannel() -> int # 获取当前的读取通道
readChannelCount() -> int # 获取读取数据的通道数量
canReadLine() -> bool # 获取是否可以按行读取
bytesToWrite() -> int # 获取缓存中等待写入的字节数量
bytesAvailable() -> int # 获取可读取的字节数量
setErrorString(text:str) -> None # 设置设备的出错信息
errorString() -> st # 获取设备的出错信息
isWritable() -> bool # 获取设备是否可以写入
isReadable() -> bool # 获取设备是否可以读取
isSequential() -> bool # 获取设备是否是顺序读取
isTextModeEnabled() -> bool # 获取设备是否能够以文本方式读写
atEnd() -> bool # 获取是否已经到达文件末尾
seek(posision:int) -> None # 移动到指定的位置
pos() -> int # 获取当前位置
reset() -> bool # 重置设备,回到起始位置
startTransaction() -> None # 对随机设备记录当前位置,对顺序设备,在内部赋值读取的数据以便恢复数据
rollbackTransaction() -> None # 回到调用startTransaction()时的位置
commitTransaction() -> None # 对顺序设备,放弃记录的数据
isTransactionStarted() -> bool # 获取是否开始记录位置
size() -> int # 获取文件大小
skip(size:int) -> int # 跳过指定数量的字节数据
waitForBytesWritten(millisecond:int) -> bool # 对于缓存设备,该方法需要将数据写到设备或进故宫msecs毫秒后返回值
waitForReadyRead(millisecond:int) -> bool # 当有数据可以读取前或经过msecs毫秒会阻止设备的运行
QIODevice
的子类 QFile
、QBuffer
和 QTcpSocke
t 等需要用 open(mode:QIODeviceBase.OpenMode)
方法 打开一个设备,用 close()
方法 关闭设备。打开设备时需要 设置打开模式,参数 mode
是 QIODeviceBase.OpenMode
类型的枚举值,可以取值如下所示,可以设置只读、只写、读写、追加和不使用缓存等模式,如果同时要选择多个选项可以用 |
连接:
QIODeviceBase.OpenModeFlag.NotOpen # 还未打开
QIODeviceBase.OpenModeFlag.ReadOnly # 以只读的方式打开
QIODeviceBase.OpenModeFlag.WriteOnly # 以只写的方式打开,如果文件不存在,则创建新文件
QIODeviceBase.OpenModeFlag.ReadWrite # 以读写的方式打开,如果文件不存在,则创建新文件
QIODeviceBase.OpenModeFlag.Append # 以追加的方式打开,新增加的内容将被追加到文件末尾
QIODeviceBase.OpenModeFlag.Truncate # 以重写的方式打开,在写入新的数据是会将原有数据全部清除,指针指向文件开头
QIODeviceBase.OpenModeFlag.Text # 在读写时,将行结束符转换成\n,在写入时将行结束符转换成本地格式
QIODeviceBase.OpenModeFlag.Unbuffered # 不使用缓存
QIODeviceBase.OpenModeFlag.NewOnly # 创建和打开新文件时,只用于QFile设备,如果文件存在,打开将会失败,该模式是只写模式
QIODeviceBase.OpenModeFlag.ExistingOnly # 打开文件时,如果文件不存在会出现错误,只适用于QFile设备
读写设备分为两种,一种是 随机设备(random-access device),另一种是 顺序设备(sequential device),用 isSequential()
方法可以 判断设备是否是顺序设备。QFile
和 QBuffer
是随机设备,QTcpSocket
和 QProcess
是顺序设备。随机设备 可以 获取设备指针的位置,将指针指向指定的位置,从指定位置读取数据。而顺序设备 只能依次读取数据。随机设备 可以用 seek(pos:int)
方法 定位,用 pos()
方法 获取位置。
读取数据 的常用方法如下:
getChar(c:bytes) # 读取一个字符,并存储到c中
peek(length:int) -> QByteArray # 读取指定数量的字节
read(length:int) -> QByteArray # 表示读取指定长度的数据
readLine(length:int=0) # 读取一行数据,参数maxlen表示允许读取的最大长度,若为0表示不受限制
readData(length:int) -> QObject # 读取数据
readAll() -> QByteArray # 读取所有数据
写入数据 的常用方法如下:
putChar(c:str) -> bool: # 写入一个字符
write(data:Union[QByteArray, bytes]) -> int # 写入字符串,返回实际写入的字节数
writeData(data:bytes, len:int) -> int # 写入数据,返回实际写入的字节数量
一些顺序设备支持多通道读写,这些通道表示独立的数据流,可以用 setCurrentReadChannel(int)
方法设置读取通道,用 setCurrentWriteChannel(int)
方法设置写入通道,用 currentReadChannel()
方法和 currentWriteChannel()
方法获取读取和写入通道。
如果要继承
QIODevice
创建自己的读写设备,需要重写readData()
和writeData()
函数。
1.2、QByteArray类
在利用 QIODevice
的子类进行读写数据时,通常返回值或参数是 QByteArray
类型的数据。QByteArray
用于 存储二进制数据,至于这些数据到底表示什么内容(字符串、数字、图片或音频等),完全由程序的解析方式决定。如果采用合适的字符编码方式(字符集),字节数组可以恢复成字符串,字符串也可以转换成字节数组。字节数组会自动添加 "\0"
作为结尾,统计字节数组的长度时,不包含末尾的 "\0"
。
用 QByteArray
创建字节数组的方法如下,其中 c
只能是一个字符。
QByteArray()
QByteArray(text:bytes, size:int=-1)
QByteArray(text:Union[QByteArray, bytes, bytearray str])
QByteArray(size:int, c:str)
用 Python 的 str(byteArray:QByteArray, encoding:str="utf-8")
函数可以将 QByteArray
数据转换成 Python 的字符串型数据。用 QByteArray
的 append(data:str)
方法可以将 Python 的字符串添加到 QByteArray
对象中,同时返回包含字符串的新 QByteArray
对象。
Python3.x 中新添加了字节串 bytes
数据类型,其功能与 QByteArray
的功能类似。如果一个字符串前面加 "b"
,就表示是 bytes
类型的数据,例如 b'hello'
。
bytes
数据和字符串的对比如下:
- 字节是计算机的语言,字符串是人类的语言,它们之间通过编码表形成对应关系。
- 字符串由若干个字符组成,以字符为单位进行操作。
bytes
由若干个字节组成,以字节为单位进行操作。bytes
和字符串除了操作的数据单元不同之外,它们支持的所有方法都基本相同。bytes
和字符串都是不可变序列,不能随意增加和删除数据。
用 xx=bytes("hello", encoding="utf-8")
方法可以将字符串 "hello"
转换成 bytes
,用 yy=str(xx, encoding="utf-8")
方法可以将 bytes
转换成字符串。
bytes
也是一个类,用 bytes()
方法可以创建一个空 bytes
对象,用 bytes(int)
方法可以创建指定长度的 bytes
对象,用 decode(encoding:str="utf-8")
方法可以对数据进行解码,bytes
的操作方法类似于字符串的操作方法。
Python 中还有一个与 bytes
类似但是可变的数组 bytearray
,其创建方法和字符串的转换方法与 bytes
相同,在 QByteArray
的各个方法中,可以用 bytes
数据的地方也可以用 bytearray
。
QByteArray
类的常用方法:
# 实例方法
append(a:Union[QByteArray, bytes]) -> QByteArray # 在末尾追加数据
append(c:str) -> QByteArray # 在末尾追加字符串
append(count:int, c:str) -> QByteArray # 在末尾追加字符串
append(s:bytes, len:int) -> QByteArray # 在末尾追加字符串
at(i:int) -> str # 根据索引获取数据
chop(n:int) -> QByteArray # 获取从末尾移除len个字节后的字节数组
clear() -> None # 清空所有字节
contains(bv:Union[QByteArray, bytes]) -> bool # 获取是否包含指定的字节数组
contains(c:str) -> bool # 获取是否包含指定的字符串
count(bv:Union[QByteArray, bytes]) -> int # 获取指定的字节数组的出现次数
count() -> int # 获取字节数组的长度
size() -> int # 获取字节数组的长度
data() -> bytes # 获取字符串
startsWith(bv:Union[QByteArray, bytes]) -> bool # 获取是否以指定的字节数组开头
startsWith(c:str) -> bool # 获取是否以指定的字符串开头
endsWith(bv:Union[QByteArray, bytes]) -> bool # 获取末尾是否时指定的字节数组
endsWith(c:str) -> bool # 获取末尾是否是指定的字符串
fill(c:str, size:int=-1) -> QByteArray # 使数组的每个数据为指定的字符,将长度调整为size
indexOf(bv:Union[QByteArray, bytes], from:int=0) -> int # 获取指定的字节数组在数组中的位置
indexOf(c:str, from:int=0) -> int # 获取指定的字符串在数组中的位置
insert(i:int, bv:Union[QByteArray, bytes]) -> QByteArray # 在指定的位置插入字节数组
insert(i:int, c:str) -> QByteArray # 在指定的位置插入字符串
insert(i:int, count:int, c:str) -> QByteArray # 在指定的位置插入字符串
isEmpty() -> bool # 是否为空,长度为0时返回True
isNull() -> bool # 内容为空返回True
toLower() -> QByteArray # 将所有字符转换为小写
isLower() -> bool # 判断是否全部都是小写
toUpper() -> QByteArray # 将所有字符转换为大写
isUpper() -> bool # 判断是否全部都是大写
lastIndexOf(bv:Union[QByteArray, bytes], from:int=-1) -> int # 获取最后索引值
lastIndexOf(c:str, from:int=-1) -> int # 获取最后索引值
length() -> int # 获取字节数组的长度
mid(index:int, len:int=-1) -> QByteArray # 从指定位置获取指定长度的数据
prepend(a:Union[QByteArray, bytes]) -> QByteArray # 在开头插入字节数组
remove(index:int, len:int) -> QByteArray # 从指定位置删除指定长度的数据
repeated(times:int) -> QByteArray # 获取重复times次后的数据
replace(index:int, len:int, s:Union[QByteArray, bytes]) -> QByteArray # 从指定位置替换指定长度的数据
replace(before:Union[QByteArray, bytes], after:Union[QByteArray, bytes]) -> QByteArray # 替换指定位置的数据
resize(size:int) -> None # 调整长度
setNum(arg__1:float, format:str="g", precision:int=6) -> QByteArray # 将浮点数转换成科学计数法数据
setNum(arg__1:int, base:int=10) -> QByteArray # 将整数转换成字节数组
split(sep:str) -> List[QByteArray] # 用分割符将字节数组分割成列表
squeeze() -> None # 释放不存储数据的内存
toBase64(options:QByteArray.Base64Option=QByteArray.Base64Option.Base64Encoding) -> QByteArray # 将字节数组转换为Base64编码
toDouble() -> Tuple[float, bool] # 转换成浮点数
toFloat() -> Tuple[float, bool] # 转换成浮点数
toHex(separator:str="0") -> QByteArray # 转换成十六进制
toShort(base:int=10) -> Tuple[int, bool] # 根据进制转换成整数
toInt(base:int=10) -> Tuple[int, bool] # 根据进制转换成整数
toLong(base:int=10) -> Tuple[int, bool] # 根据进制转换成整数
toLongLong(base:int=10) -> Tuple[int, bool] # 根据进制转换成整数
toUShort(base:int=10) -> Tuple[int, bool] # 根据进制转换成整数
toUInt(base:int=10) -> Tuple[int, bool] # 根据进制转换成整数
toULong(base:int=10) -> Tuple[int, bool] # 根据进制转换成整数
toULongLong(base:int=10) -> Tuple[int, bool] # 根据进制转换成整数
# 转换成百分比编码
toPercentEncoding(exclude:QByteArray=QByteArray(), include:QByteArray=QByteArray(), percent="%") -> QByteArray
simplified() -> QByteArray # 去除内部、开始和结尾的空白字符
left(len:int) -> QByteArray # 从左侧获取指定长度的字节
right(len:int) -> QByteArray # 从右侧获取指定长度的字节
truncate(pos:int) -> None # 截断前pos个字符数据
# 静态方法
# 从Base645编码中解码
fromBase64(base64:Union[QByteArray, bytes], options:QByteArray.Base64Option=QByteArray.Base64Option.Base64Encoding) -> QByteArray
# 从Base64编码中解码
fromBase64Encoding(base64:Union[QByteArray, bytes], options:QByteArray.Base64Option=QByteArray.Base64Option.Base64Encoding) -> QByteArray
fromHex(hexEncoded:Union[QByteArray, bytes]) -> QByteArray # 从十六进制数据中解码
fromRawData(data:Union[QByteArray, bytes], size:int=-1) -> QByteArray # 用前size个原生字节构建字符数组
fromPercentEncoding(pctEncoded:Union[QByteArray, bytes], percent:str="%") -> QByteArray # 从百分号编码中解码
number(arg__1:int, base:int=10) -> QByteArray # 将整数转换为字节数组
number(arg__1:float, format:str="g", precision:int=6) # 将浮点数转换为字节数组
用 setNum(float,format='g',precision=6)
方法或 number(float,format='g',precision=6)
方法可以 将浮点数转换成用科学计数法表示的数据,其中格式 format
可以取 'e'
、'E'
、'f'
、'g'
或 'G'
,'e'
表示的格式如 -9.9e+999,'E'
表示的格式如 9.9E+999,'f'
表示的格式如 9.9,如果取 'g'
表示视情况选择 'e'
或 'f'
,如果取 'G'
表示视情况选择 'E'
或 'f'
。
用静态方法 fromBase64(Union[QByteArray,bytes],options=QByteArray.Base64Encoding)
可以 把 Base64 编码数据解码,用 toBase64(options:QByteArray.Base64Option)
方法可以 转换成 Base64 编码,其中参数 options
可以取值如下:
QByteArray.Base64Option.Base64Encoding
QByteArray.Base64Option.Base64UrlEncoding
QByteArray.Base64Option.KeepTrailingEquals
QByteArray.Base64Option.OmitTrailingEquals
QByteArray.Base64Option.IgnoreBase64DecodingErrors
QByteArray.Base64Option.AbortOnBase64DecodingErrors
1.3、QFile读取数据
QFile
继承自 QIODevice
,会继承 QIODevice
的方法。QFile
可以读写文本文件和二进制文件,可以单独使用,也可以与 QTextStream
和 QDataStream
一起使用。
用 QFile
类创建实例对象的方法如下所示:
QFile()
QFile(parent:QObject)
QFile(name:Union[str, bytes, os.PathLike])
QFile(name:Union[str, bytes, os.PathLike], parent:QObject)
其中 parent
是继承自 QObject
的实例,name
是 要打开的文件。
QFile
类的常用方法:
# 实例方法
open(flags:QIODeviceBase.OpenMode) -> None # 按照模式打开文件
setFileName(name:Union[str, bytes, os.PathLike]) -> None # 设置文件路径和名称
fileName() -> str # 返回文件名称
flush() -> None # 将缓存中的数据写入到文件中
close() -> None # 关闭文件
# 静态方法
setPermissions(filename:QFileDevice.Permission) # 设置权限
exists(fileName:str) -> bool # 检查文件是否存在
copy(fileName:str, newName:str) -> None # 复制打开的文件到新文件
remove(fileName:str) -> None # 删除文件
rename(oldName:str, newName:str) -> None # 重命名文件
新建一个 template.py 文件。
from PySide6.QtCore import QFile
if __name__ == "__main__":
file_path = "./文件.txt"
file = QFile(file_path) # 1.创建一个文件信息
file.open(QFile.OpenModeFlag.WriteOnly) # 2.以只写模式打开文件
file.write("你好,世界!\n".encode("utf-8")) # 3.向文件中写入内容
file.write("hello world!\n".encode("utf-8"))
file.close() # 4.关闭文件
file.open(QFile.OpenModeFlag.ReadOnly) # 5.以只读模式打开文件
while not file.atEnd(): # 6.判断是否读到末尾
text = file.readLine().toStdString().strip() # 7.从文件中读取一行
print(text)
file.close() # 8.关闭文件
二、用流方式读取数据
从本机上读写数据更简便的方法是用流(stream)方式,读写文本数据用 文本流 QTextStream
,读写二进制数据用 数据流 QDataStream
。用 数据流 可以将文本、整数和浮点数以 二进制格式 保存到文件中,也可以将常用的类的实例保存到文件中,可以从文件中直接读取类的实例。
2.1、文本流
文本流 是指一段文本数据,可以理解成管道中流动的一股水,管道接到什么设备上,水就流入什么设备内。QTextStream
是 文本流类,它可以连接到 QIODevice
或 QByteArray
上,可以将一段文本数据写入 QIODevice
或 QByteArray
上,或者从 QIODevice
或 QByteArray
上读取文本数据。QTextStream
适合写入大量的有一定格式要求的文本。
用 QTextStream
定义文本流的方法如下所示,可以看出其连接的设备可以是 QIODevice
或 QByteArray
。
QTextStream()
QTextStream(device:QIODevice)
QTextStream(array:Union[QByteArray, bytes], openMode=QIODeviceBase.ReadWrite)
QTextStream
类的常用方法如下:
setDevice(device:QIODevice) -> None # 设置操作的设备
device() -> QIODevice # 获取操作的设备
setEncoding(encoding:QStringConverter.Encoding) -> None # 设置编码
encoding() -> QStringConverter.Encoding # 获取编码
setAutoDetectUnicode(enabled:bool) -> None # 设置自动检测编码
setGenerateByteOrderMark(generate:bool) -> None # 如果设置成True,那么在写入文件时,会写入BOM
setFieldWidth(width:int) -> None # 设置数据流的宽度,如果为0,则宽度时数据的宽度
fieldWidth() -> int # 获取数据流的宽度
setFieldAlignment(alignment:QTextStream.FieldAlignment) -> None # 设置数据在数据流内的对齐方式
fieldAlignment() -> QTextStream.FieldAlignment # 获取数据在数据流内的对齐方式
setPadChar(ch:str) -> None # 设置填充字符
padChar() -> str # 获取填充字符
setIntegerBase(base:int) -> None # 设置整数的进制
integerBase() -> int # 获取整数的进制
setNumberFlags(flags:QTextStream.NumberFlags) -> None # 设置数字的标识
numberFlags() -> QTextStream.NumberFlags # 获取数字的标识
setRealNumberNotation(notation:QTextStream.NumberNotation) -> None # 设置实数的标记方法
realNumberNotation() -> QTextStream.NumberNotation # 获取实数的标记方法
setRealNumberPrecision(precision:int) -> None # 设置实数的精度
realNumberPrecision() -> int # 获取实数的精度
setStatus(status:QTextStream.Status) -> None # 设置状态
status() -> QTextStream.Status # 获取状态
resetStatus() -> None # 重置状态
read(maxlen:int) -> str # 读取指定长度的数据
readAll() -> str # 读取所有数据
readLine(maxlen:int=0) -> str # 按行读取数据,maxlen是一次允许度的最大长度
seek(pos:int) -> None # 定位到指定位置
pos() -> int # 获取当前位置
flush() -> None # 将缓存中的数据写到设备中
atEnd() -> bool # 判断是否已经到达文件末尾
skipWhiteSpace() -> None # 忽略空字符,直到非空字符或达到末尾
reset() -> None # 重置除字符串和缓冲以外的其它设置
QTextStream
的连接设备可以在创建文本数据流时定义,也可以用 setDevice(device:QIODevice)
方法来定义,用 device()
方法 获取连接的设备。QTextStream
与 QFile
结合可读写文本文件,与 QTcpSocket
、QUdpSocket
结合可读写网络文本数据。
QTextStream
没有专门的写数据的方法,需要用流操作符 "<<"
来完成写入数据。"<<"
的左边是 QTextStream
实例,右边可以是字符串、整数或浮点数,如果要同时写入多个数据,可以把多个 "<<"
写到一行中。
用 setEncoding(QStringConverter.Encoding)
方法 设置文本流读写数据的编码,文本流支持的编码如下:
QStringConverter.Encoding.Utf8
QStringConverter.Encoding.Utf16
QStringConverter.Encoding.Utf16LE
QStringConverter.Encoding.Utf16BE
QStringConverter.Encoding.Utf32
QStringConverter.Encoding.Utf32LE
QStringConverter.Encoding.Utf32BE
QStringConverter.Encoding.Latin1
QStringConverter.Encoding.System # 系统默认的编码
用 setAutoDetectUnicode(on:bool)
方法 设置是否自动识别编码,如果能识别出则会替换已经设置的编码。如果 setGenerateByteOrderMark(generate:bool)
为 True
且采用 UTF 编码,会在写入数据前在数据前面添加自动查找编码标识 BOM(byte-order mark)
,即字节顺序标记,它是插入到以 UTF-8、UTF-16 或 UTF-32 编码 Unicode 文件开头的特殊标记,用来识别 Unicode 文件的编码类型。
用 setFieldWidth(width:int=0)
方法 设置写入一段数据流的宽度,如果真实数据流的宽度小于设置的宽度,可以用 setFieldAlignment(allignment:QTextStream.FieldAlignment)
方法 设置数据在数据流内的对齐方式,其余位置的数据用 setPadChar(c:str)
设置的字符来填充。参数 allignment
是 QTextStream.FieldAlignment
类型的枚举参数,用于 指定对齐方式,可以取值如下:
QTextStream.FieldAlignment.AlignLeft # 左对齐
QTextStream.FieldAlignment.AlignRight # 右对齐
QTextStream.FieldAlignment.AlignCenter # 居中
QTextStream.FieldAlignment.AlignAccountingStyle # 居中,但数值的符号位靠左
用 setNumberFlags(flag:QTextStream.NumberFlag)
方法 设置输出整数和浮点数时数值的表示样式,其中参数 flag
是 QTextStream.NumberFlag
类型的枚举值,可以取值如下:
QTextStream.NumberFlag.ShowBase # 以进制作为前缀
QTextStream.NumberFlag.ForcePoint # 强制显示小数点
QTextStream.NumberFlag.ForceSign # 强制显示正负号
QTextStream.NumberFlag.UppercaseBase # 进制显示成大写
QTextStream.NumberFlag.UppercaseDigits # 表示10~35的字母用大写
用 setRealNumberNotation(notation:QTextStream.RealNumberNotation)
方法 设置浮点数的标记方法,参数 notation
是 QTextStream.RealNumberNotation
类型的枚举值,可以取值如下:
QTextStream.RealNumberNotation.ScientificNotation # 科学计数法
QTextStream.RealNumberNotation.FixedNotation # 固定小数点
QTextStream.RealNumberNotation.SmartNotation # 视情况选择合适的方法
用 setStatus(status:QTextStream.Status)
方法 设置数据流的状态,参数 status
是 QTextStream.Status
类型的枚举值,可以取值如下:
QTextStream.Status.Ok # 文本流正常
QTextStream.Status.ReadPastEnd # 读取过末尾
QTextStream.Status.ReadCorruptData # 读取了有问题的数据
QTextStream.Status.WriteFailed # 不能写入数据
修改 template.py 文件的内容。
from PySide6.QtCore import QFile, QTextStream, QStringConverter
if __name__ == "__main__":
file_path = "./文件.txt"
file = QFile(file_path) # 1.创建一个文件信息
file.open(QFile.OpenModeFlag.WriteOnly) # 2.以只写模式打开文件
writer = QTextStream(file) # 3.创建文本流
writer.setEncoding(QStringConverter.Encoding.Utf8) # 4.设置编码
writer.setFieldWidth(0) # 5.设置域宽
writer.setFieldAlignment(QTextStream.FieldAlignment.AlignCenter) # 6.设置对齐方式
writer << "你好,世界!\n" # 7.写入数据
writer << "hello world!\n"
writer.flush() # 8.刷新写入
file.close() # 9.关闭文件
file.open(QFile.OpenModeFlag.ReadOnly) # 10.以只读模式打开信息
while not file.atEnd(): # 11.判断是否读到末尾
text = file.readLine() # 12.从文件中读取一行
print(str(text, encoding="utf-8").strip())
file.close() # 13.关闭文件
2.2、数据流
数据流 QDataStream
用于 直接读写二进制的数据和网络通信数据,二进制数据具体表示的物理意义由读写方法以及后续的解码决定,数据流的读写与具体的操作系统无关。
用 QDataStream
类创建数据流对象的方法如下所示,它可以连接到继承自 QIODevice
的设备或 QByteArray
上。
QDataStream()
QDataStream(device:QIODevice)
QDataStream(device:Union[QByteArray, bytes])
QDataStream(device:Union[QByteArray, bytes], flags:QIODeviceBase.OpenMode)
QDataStream
类的常用方法如下:
setDevice(device:QIODevices) -> None # 设置设备
setByteOrder(arg__1:QDataStrem.ByteOrder) -> None # 设置字节序
byteOrder() -> QDataStrem.ByteOrder # 获取字节序
setFloatingPointPrecision(precision:QDataStrem.FloatingPointPrecision) -> None # 设置读写浮点数的精度
setStatus(status:QDataStrem.Status) -> None # 设置流状态
resetStatus() -> None # 重置流状态
status() -> QDataStrem.Status # 获取流状态
setVersion(version:int) -> None # 设置版本号
version() -> int # 获取版本号
skipRawData(len:int) -> int # 跳过原生数据,返回跳过的字节数量
commitTransaction() -> None # 完成数据块
rollbackTransaction() -> None # 回到数据块的记录点
abortTransaction() -> None # 放弃对数据块的记录
atEnd() -> bool # 获取是否还有数据可读
创建数据流对象时,可以设置数据流关联的设备,也可用 setDevice(device:QIODevice)
方法 重新设置关联的设备,用 device()
方法 获取关联的设备。用 setVersion(version:int)
方法 设置版本号。不同版本号的数据的存储格式有所不同,因此建议设置版本号。到目前为止,版本号可取值如下:
QDataStream.Qt_1_0
QDataStream.Qt_2_0
QDataStream.Qt_3_0
QDataStream.Qt_3_1
QDataStream.Qt_3_3
QDataStream.Qt_4_0 ~ QDataStream.Qt_4_9
QDataStream.Qt_5_0 ~ QDataStream.Qt_5_15
QDataStream.Qt_6_0 ~ QDataStream.Qt_6_2
用 setFloatingPointPrecision(precision:QDataStream.FloatingPointPrecision)
方法 设置读写浮点数的精度,其中参数 precision
是 QDataStream.FloatingPointPrecision
类型的枚举值,可以取值如下:
QDataStream.FloatingPointPrecision.SinglePrecision
QDataStream.FloatingPointPrecision.DoublePrecision
对于版本高于 Qt_4_6
且精度设置为 DoublePrecision
的浮点数是 64
位精度,对于版本高于 Qt_4_6
且精度设置为 SinglePrecision
的浮点数是 32
位精度。
用 setByteOrder(order:QDataStream.ByteOrder)
方法 设置字节序,参数 order
是 QDataStream.ByteOrder
类型的枚举值,可以取值如下:
QDataStream.ByteOrder.BigEndian # 大端字节序,默认值
QDataStream.ByteOrder.LittleEndian # 小端字节序
大端字节序的高位字节在前,低位字节在后,小端字节序与此相反。
用 skipRawData(length:int)
方法可以 跳过指定长度的原生字节,返回真实跳过的字节数。原生数据是机器上存储的二进制数据,需要用户自己解码。
用 startTransaction()
方法可以 记录一个读数据的点,对于顺序设备会在内部复制读取的数据,对于随机设备会保存当前数据流的位置。用 commitTransaction()
方法 确认完成记录一个数据块,当数据流的状态是已经超过末尾时,用该方法会回到数据块的记录点,如果状态是数据有误,则会放弃记录的数据块。用 rollbackTransaction()
方法 在确认完成记录数据块之前返回到记录点。用 abortTransaction()
方法 放弃对数据块的记录,并不影响当前读数据的位置。
数据流用于读/写整数、浮点数和逻辑值的方法和数值的范围如下所示。需要特别注意的是,在读数值时,必须按照写入数值时所使用的字节数来读,否则读取的数值不是写入时的数值。
readInt8() -> int # 在1个字节上读带正负号整数
writeInt8(arg__1:int) -> None # 在1个字节上写带正负号整数
readInt16() -> int # 在2个字节上读带正负号整数
writeInt16(arg__1:int) -> None # 在2个字节上写带正负号整数
readInt32() -> int # 在4个字节上读带正负号整数
writeInt32(arg__1:int) -> None # 在4个字节上写带正负号整数
readInt64() -> int # 在8个字节上读带正负号整数
writeInt64(arg__1:int) -> None # 在8个字节上写带正负号整数
readUInt8() -> int # 在1个字节上读无符号整数
writeUInt8(arg__1:int) -> None # 在1个字节上写无符号整数
readUInt16() -> int # 在2个字节上读无符号整数
writeUInt16(arg__1:int) -> None # 在2个字节上写无符号整数
readUInt32() -> int # 在4个字节上读无符号整数
writeUInt32(arg__1:int) -> None # 在4个字节上写无符号整数
readUInt64() -> int # 在8个字节上读无符号整数
writeUInt64(arg__1:int) -> None # 在8个字节上写无符号整数
readBool() -> int # 在1个字节上读逻辑值
writeBool(arg__1:int) -> None # 在1个字节上写逻辑值
readFloat() -> int # 在4个字节上读带正负号浮点数
writeFloat(arg__1:int) -> None # 在4个字节上写带正负号浮点数
readDouble() -> int # 在8个字节上读带正负号浮点数
writeDouble(arg__1:int) -> None # 在8个字节上写带正负号浮点数
数据流用于读/写字符串的方法如下所示。读/写字符串时不需要指定字节数量,系统会根据字符串的大小来决定所使用的字节数。
readString() -> str # 读文本
writeString(arg__1:str) -> None # 写文本
readQString() -> List[str] # 读文本
writeQString(arg__1:Sequence[str]) -> None # 写文本
readQStringList() -> List[str] # 读文本列表
writeQStringList(arg__1:Sequence[str]) -> None # 写文本列表
from PySide6.QtCore import QFile, QDataStream
if __name__ == "__main__":
file_path = "./文件.txt"
file = QFile(file_path) # 1.创建一个文件信息
file.open(QFile.OpenModeFlag.WriteOnly) # 2.以只写模式打开文件
writer = QDataStream(file) # 3.创建文本流
writer.writeQString("你好,世界!\n") # 4.向文件中写入数据
writer.writeString("hello world!\n")
writer.writeInt32(27185)
writer.writeFloat(27185.27185)
file.close() # 5.关闭文件
file.open(QFile.OpenModeFlag.ReadOnly) # 6.以只读模式打开文件
value = writer.readQString().strip() # 7.从文件中读取数据
print(value)
value = writer.readString().strip()
print(value)
value = writer.readInt32()
print(value)
value = writer.readFloat()
print(value)
file.close() # 8.关闭文件
三、临时数据的保存
3.1、临时文件
QTemporaryFile
类用于创建临时文件,它继承自 QFile
,当用 Open()
方法打开设备时创建临时文件,并保证临时文件名是唯一的,不会和本机上的文件同名。
用 QTemporaryFile
创建临时文件对象的方法如下:
QTemporaryFile()
QTemporaryFile(parent:QObject)
QTemporaryFile(templateName:str)
QTemporaryFile(templateName:str, parent:QObject)
其中 templateName
是 文件名称模板,或者不用模板而用 指定文件名,parent
是继承自 QObject
类的实例对象。模板的文件名中包含 6 个或 6 个以上的大写 "X"
,扩展名可以自己指定,例如 QTemporaryFile("XXXXXXXX.sdb")
、QTemporaryFile("abXXXXXXXXcd.sdb")
。
如果没有使用模板,而使用 具体文件名,则 临时文件名是在文件名基础上添加新的扩展名,如果 指定了父对象,则用 应用程序的名称(用 app.setApplicationName(name:str)
设置)再加上新的扩展名作为临时文件名。如果 没有使用模板或指定文件名,则 存放临时文件的路径是系统临时路径,可以通过 QDir.tempPath()
方法 获取系统临时路径;如果使用模板或指定文件名,则存放到当前路径下,当前路径可以用 QDir.currentPath()
方法查询。
QTemporaryFile
类常用方法如下:
open() -> bool # 创建并打开临时文件
fileName() -> str # 获取临时文件名
setAutoRemove(b:bool) -> None # 设置是否自动删除临时文件
autoRemove() -> bool # 获取是否自动删除临时文件
setFileTemplate(name:str) -> None # 设置临时文件的模板
fileTemplate() -> str # 获取临时文件的模板
创建临时文件对象后,用 open()
方法 打开文件,这时会 生成临时文件,临时文件名可以用 fileName()
方法获取,临时文件的打开方式是读写模式(QIODeviceBase.OpenModeFlag.ReadWrite
)。打开临时文件后,可以按照前面介绍的写入和读取方法来读写数据。用 setAutoRemove(on:bool)
方法 设置临时文件对象销毁后临时文件是否自动删除,默认为 True
。
3.2、临时路径
与创建临时文件类似,也可以创建临时路径,应保证所创建的临时路径不会覆盖本机上的路径,程序退出时自动删除临时路径。
创建临时路径的方法如下所示:
QTemporaryDir()
QTemporaryDir(templateName:str)
QTemporaryDir
类常用方法如下:
path() -> str # 获取创建的临时路径
isValid() -> bool # 检查临时路径是否创建成功
errorString() -> str # 获取错误信息
filePath(fileName:str) -> str # 获取临时路径中的文件的路径
setAutoRemove(b:bool) -> None # 设置是否自动移除临时路径
autoRemove() -> bool # 获取是否自动移除临时路径
remove() -> bool # 移除临时路径
3.3、存盘
QSaveFile
用来 保存文本文件和二进制文件,在写入操作失败时不会导致已经存在的数据丢失。QSaveFile
执行写操作时,会先将内容写入到一个临时文件中,如果没有错误发生,则调用 commit()
方法来 将临时文件中的内容移到目标文件中。这样能确保目标文件中的数据在写操作发生错误时不会丢失,也不会出现部分写入的情况。
一般使用 QSaveFile
在磁盘上保存整份文档。QSaveFile
会自动检测写入过程中所出现的错误,并记住所有发生的错误,在调用 commit()
方法时放弃临时文件。
用 QSaveFile
创建保存文件的方法如下所示:
QSaveFile(parent:QObject=None)
QSaveFile(name:str)
QSaveFile(name:str, parent:QObject)
其中 name
是 文件名,parent
是继承自 QObject
的对象。
QSaveFile
常用方法如下:
setFileName(name:str) -> None # 设置保存数据的目标文件
fileName() -> str # 获取目标文件
open(mode:QIODeviceBase.OpenMode) -> bool # 打开文件
commit() -> bool # 从临时文件中将数据写入到目标文件中
cancelWriting() -> None # 取消将数据写入到目标文件中
setDirectWriteFallback(enabled:bool) -> None # 设置是否直接向目标文件中写数据
directWriteFallback() -> bool # 获取是否直接向目标文件中写数据
writeData(data:bytes, len:int) -> int # 重写该函数,写入字符串,并返回实际写入的字节串的数量
用 open(flags:QIODeviceBase.OpenMode)
方法 打开文件,并 创建临时文件,如果创建临时文件出错则返回 False
。可以使用 QDataStream
或 QTextStream
进行读写,也可以使用从 QIODevice
继承的 read()
、readLine()
、write()
等方法进行读写。
QSaveFile
不能调用 close()
函数,而是通过调用 commit()
函数 完成数据的保存。如果没有调用 commit()
函数,则 QSaveFile
对象销毁时,会丢弃临时文件。
当应用程序出错时,用 cancelWriting()
方法可以 放弃写入的数据,即使又调用了 commit()
,也不会发生真正保存文件操作。
QSaveFile
会在目标文件的同一目录下创建一个临时文件,并自动进行重命名。但如果由于该目录的权限限制不允许创建文件,则调用 open()
会失败。
为了解决这个问题,即能让用户编辑一个现存的文件,而不创建新文件,可使用 setDirectWriteFallback(True)
方法,这样在调用 open()
时就会 直接打开目标文件,并向其写入数据,而不使用临时文件。但是在写入出错时,不能使用 cancelWriting()
方法取消写入。
3.4、缓存
对于程序中反复使用的一些临时数据,如果将其保存到文件中,则反复读取这些数据要比从缓存读取数据慢得多。缓存是 内存中一段连续的存储空间,QBuffer
提供了可以从缓存读取数据的功能,在多线程之间进行数据传递时选择缓存比较方便。
缓存属于共享资源,所有线程都能进行访问。QBuffer
和 QFile
一样,也是一种读写设备,它继承自 QIODevice
,可以用 QIODevice
的读写方法从缓存中读写数据,也可以与 QTextStream
和 QDataStream
结合读写文本数据和二进制数据。
用 QBuffer
创建缓存设备的方法如下:
QBuffer(parent=:QObject=None)
QBuffer(buffer:Union[QByteArray, bytes], parent=:QObject=None)
其中 parent
是继承自 QObject
的实例对象。定义 QBuffer
需要一个 QByterArray
对象,也可不指定 QByteArray
,系统会给 QBuffer
创建一个默认的 QByteArray
对象。
QBuffer
类常用方法如下:
setBuffer(a:Union[QByteArray, byte]) -> None # 设置缓存
buffer() -> QByteArray # 获取缓存中的QByteArray对象
setData(data:Union[QByteArray, byte]) -> None # 给缓存设置QByteArray对象
data() -> QByteArray # 获取缓存中的QByteArray对象
open(mode:QIODeviceBase.OpenMode) -> bool # 打开缓存
close() -> None # 关闭缓存
readData(data:bytes, maxlen:int) -> object # 重写该函数,读取指定的最大数量的字节数据
writeData(data:bytes, len:int) -> int # 重写该函数,写入数据
canReadLine() -> bool # 获取是否可以按行读取
seek(pos:int) -> bool # 定位到指定位置
pos() -> int # 获取指向缓存内部指针的位置
atEnd() -> bool # 获取是否达到尾部
size() -> int # 获取缓存中字节的总数
默认情况下,系统会自动给 QBuffer
的实例创建默认的 QByteArray
对象,可以用 buffer()
方法或 data()
方法获取 QByteArray
对象,也可用 setBuffer(data:QByteArray)
方法 设置缓存。QBuffer
需要用 open(mode:QIODeviceBase.OpenMode)
方法 打开缓存,成功则返回 True
,打开后可以读写数据;用 close()
方法 关闭缓存。
from PySide6.QtCore import QFile, QBuffer, QDataStream
if __name__ == "__main__":
buffer = QBuffer() # 1.创建缓存
buffer.open(QBuffer.OpenModeFlag.WriteOnly) # 2.打开缓存
writer = QDataStream(buffer) # 3.创建文本流
writer.writeQString("你好,世界!\n") # 4.向文件中写入数据
writer.writeString("hello world!\n")
writer.writeInt32(27185)
writer.writeFloat(27185.27185)
buffer.close() # 5.关闭文件
buffer.open(QFile.OpenModeFlag.ReadOnly) # 6.以只读模式打开缓存
value = writer.readQString().strip() # 7.从缓存中读取数据
print(value)
value = writer.readString().strip()
print(value)
value = writer.readInt32()
print(value)
value = writer.readFloat()
print(value)
buffer.close() # 8.关闭文件
四、文件管理
4.1、文件信息
文件信息 QFileInfo
用于 查询文件的信息,如文件的相对路径、绝对路径、文件大小、文件权限、文件的创建及修改时间等。
用 QFileInfo
类创建文件信息对象的方法如下所示:
QFileInfo()
QFileInfo(file:QFileDevice)
QFileInfo(file:Union[str, bytes, os.PathLike])
QFileInfo(dir:Union[QDir, str], file:Union[str, bytes, os.PathLike])
其中 file
是 需要获取文件信息的文件,QFileInfo(dir:QDir,file:str)
表示用 dir
路径下的 file
文件创建文件信息对象。
QFileInfo
类的常用方法如下:
setFile(file:Union[str, bytes]) -> None # 设置需要获取文件信息的文件
setFile(file:QFileDevice) -> None # 设置需要获取文件信息的文件
setFile(dir:Union[QDir, str], file:str) -> None # 设置需要获取文件信息的文件
setCaching(on:bool) -> None # 设置是否使用缓存
refresh() -> None # 刷新文件信息
absoluteDir() -> QDir # 获取绝对路径目录
absoluteFilePath() -> str # 获取绝对路径
absolutePath() -> str # 获取绝对路径
baseName() -> str # 获取第一个"."之前的文件名
completeBaseName() -> str # 获取最后一个"."之前的文件名
suffix() -> str # 获取扩展名,不包含"."
completeSuffix() -> str # 获取第一个"."之后文件名,包含扩展名
fileName() -> str # 获取文件名,包含扩展名,不包含路径
path() -> str # 获取路径,不包含文件名
filePath() -> str # 获取路径和文件名
canonicalFilePath() -> str # 获取绝对路径和文件名,路劲中不含链接符号和多余的".."及"."
canonicalPath() -> str # 获取绝对路径,路径中不含链接符号和多余的".."及"."
birthTime() -> QDateTime # 获取创建时间
lastModified() -> QDateTime # 获取最后修改时间
dir() -> QDir # 获取路径
group() -> str # 获取文件组
exists() -> bool # 获取文件是否存在
isAbsolute() -> bool # 是否绝对路径
isDir() -> bool # 是否为目录
isFile() -> bool # 是否为文件
isReadable() -> bool # 是否可读文件
isWritable() -> bool # 是否可写文件
isExecutable() -> bool # 是否可执行文件
isHidden() -> bool # 是否隐藏文件
isRelative() -> bool # 是否相对路径
isRoot() -> bool # 是否根目录
isShortcut() -> bool # 是否为快捷方式
isSymLink() -> bool # 是否为连接符号或快捷方式
isSymbolicLink() -> bool # 是否为连接符号
makeAbsolute() -> bool # 转换为绝对路径
owner() -> str # 获取文件所有者
ownerId() -> int # 获取文件所有者ID
size() -> int # 获取文件大小
symLinkTarget() -> str # 获取被链接文件的绝对路径
可以在创建 QFileInfo
对象时 设置要获取文件信息的文件,也可以用 setFile(dir:Union[QDir,str],file:str)
、setFile(file:Union[str,bytes])
或 setFile(file:QFileDevice)
方法 重新设置要获取文件信息的文件。
QFileInfo
提供了一个 refresh()
函数,用于 重新读取文件信息。如果想关闭该缓存功能,以确保每次访问文件时都能获取当前最新的信息,可以通过 setCaching(False)
方法来完成设置。
from PySide6.QtCore import QFile, QFileInfo
if __name__ == "__main__":
file_path = "./文件.txt"
file = QFile(file_path) # 1.创建一个文件信息
file.open(QFile.OpenModeFlag.ReadWrite) # 2.以读读写模式打开文件
file.write("你好,世界!".encode("utf-8")) # 3.向文件中写入内容
file.close() # 4.关闭文件
file_info = QFileInfo(file_path) # 5.获取文件的详情信息对象
# 6.读取文件的详情信息
print("文件的大小:", file_info.size())
print("文件上次修改的时间:", file_info.lastModified())
print("文件上次读取的时间:", file_info.lastRead())
print("文件是否可读:", file_info.isReadable())
4.2、路径管理
路径管理 QDir
用于管理路径和文件,它的一些功能与 QFileInfo
的功能相同。
用 QDir
创建路径管理对象的方法如下:
QDir(path:Union[QDir, str])
QDir(path:Union[str, bytes, os.PathLike])
QDir(path:Union[str, bytes, os.PathLike], nameFilter:str, sort:QDir.SortFlag=QDir.IgnoreCase, filter:QDir.Filters=QDir.AllEntries)
其中,path
是 路径,nameFilter
是 名称过滤器,filters
是枚举类型 QDir.Filter
,是 属性过滤器,sort
是 枚举类型 QDir.SortFlag
,指定排序规则。
参数 filters
是 QDir.Filter
的类型的枚举值,可以取值如下:
QDir.Filter.Dirs # 列出满足条件的路径
QDir.Filter.AllDirs # 所有路径
QDir.Filter.Files # 文件
QDir.Filter.Drives # 驱动器
QDir.Filter.NoSymLinks # 没有链接文件
QDir.Filter.NoDot # 没有"."
QDir.Filter.NoDotDot # 没有".."
QDir.Filter.NoDotAndDotDot # 没有"."和".."
QDir.Filter.AllEntries # 所有路径、文件和驱动器
QDir.Filter.Readable # 可读文件
QDir.Filter.Writable # 可写文件
QDir.Filter.Executable # 可执行文件
QDir.Filter.Modified # 可修改文件
QDir.Filter.Hidden # 可隐藏文件
QDir.Filter.System # 系统文件
QDir.Filter.CaseSensitive # 区分大小写
参数 sort
是 QDir.SortFlag
类型的枚举值,可以取值如下:
QDir.SortFlag.Name
QDir.SortFlag.Time
QDir.SortFlag.Size
QDir.SortFlag.Type
QDir.SortFlag.Unsorted
QDir.SortFlag.NoSort
QDir.SortFlag.DirsFirst
QDir.SortFlag.DirsLast
QDir.SortFlag.Reversed
QDir.SortFlag.IgnoreCase
QDir.SortFlag.LocaleAware
QDir
类常用方法如下:
# 实例方法
setPath(path:Union[str, bytes]) -> None # 设置路径
path() -> str # 获取路径
absolutePath() -> str # 获取绝对路径
absoluteFilePath(fileName:str) -> str # 获取绝对路径
relativeFilePath(fileName:str) -> str # 获取相对路径
canonicalPath() -> str # 获取不含"."和".."的路径
cd(dirName:str) -> bool # 更改路径
cdUp() -> bool # 更改路径到上一级
dirName() -> str # 获取最后一级的目录或文件名
setNameFilters(nameFilters:Sequence[str]) -> None # 设置文件名过滤器
setFilter(filter:QDir.Filter) -> None # 设置属性过滤器
setSorting(sort:QDir.SortFlag) -> None # 设置排序规则
# 根据过滤器和排序规则,获取路径下的所有文件信息和子路径信息
entryInfoList(filters:QDir.Filter=QDir.Filter.NoFilter, sort:QDir.SortFlag=QDir.SortFlag.NoSort) -> List[QFileInfo]
entryInfoList(nameFilters:Sequence[str], filters:QDir.Filter=QDir.Filter.NoFilter, sort:QDir.SortFlag=QDir.Filter.NoFilter) - List[QFileInfo]
entryList(filters:QDir.Filter=QDir.Filter.NoFilter, sort:QDir.SortFlag=QDir.Filter.NoFilter) -> List[str]
entryList(nameFilters:Sequence[str], filters:QDir.Filter=QDir.Filter.NoFilter, sort:QDir.SortFlag=QDir.Filter.NoFilter) -> List[str]
exists() -> bool # 判断路径或文件是否存在
exists(name:str) -> bool # 判断路径或文件是否存在
isAbsolute() -> bool # 获取是否是绝对路径
isRelative() -> bool # 获取是否是相对路径
isRoot() -> bool # 获取是否是根路径
isReadable() -> bool # 获取文件是否可读
# 获取路径是否为空
isEmpty(filters:QDir.Filter=QDir.Filter.NoFilter=QDir.Filters(QDir.Filter.AllEntries | QDir.Filter.NoDotAndDotDot))
makeAbsolute() -> bool # 转换到绝对路径
mkdir(dirName:str) -> bool # 创建子路径,路径已存在,则返回False
mkpath(dirPath:str) -> bool # 创建多级目录,成功返回True
refresh() -> None # 刷新缓存
remove(fileName:str) -> bool # 移除文件
removeRecursively() -> bool # 删除目录
rmdir(dirName:str) -> bool # 删除目录
rmpath(dirPath:str) -> bool # 删除目录
rename(oldName:str, newName:str) -> bool # 重命名文件或目录
# 静态方法
cleanPath(path:str) -> str # 返回移除多余符号的路径
drives() -> List[QFileInfo] # 获取根文件信息列表
setSearchPaths(prefix:str, searchPaths:Sequence[str]) -> None # 设置搜索路径
home() -> QDir # 获取系统的用户路径
homePath() -> str # 获取系统的用户路径
isAbsolutePath(path:str) -> bool # 判断路径是否是绝对路径
isRelativePath(path:str) -> bool # 判断路径是否是相对路径
listSeparator() -> str # 获取系统列表分割符
separator() -> str # 获取系统路径分割符
root() -> QDir # 获取根目录
rootPath() -> str # 获取根目录
setCurrent(path:str) -> bool # 设置当前路径
temp() -> QDir # 获取临时目录
tempPath() -> str # 获取临时目录
fromNativeSeparators(pathName:str) -> str # 获取用"/"分割的路径
toNativeSeparators(pathName:str) -> str # 转换成用本机系统使用的分割符分割的路径
修改 template.py 文件的内容。
from PySide6.QtCore import QDir
if __name__ == "__main__":
path = "./template/test"
dir = QDir(path) # 1.创建一个文件信息
# 2.如果文件夹不存在,则创建
if not dir.exists(path):
dir.mkdir(path)
dir.cd("E://") # 3.切换目录
print("是否是根目录:", dir.isRoot())
print("是否是绝对路径:", dir.isAbsolute())
print("是否是相对路径:", dir.isRelative())
print("是否可读:", dir.isReadable())
dir_list = dir.entryList()
for item in dir_list:
print(item)
4.3、文件和路劲监视器
QFileSystemWatcher
是 文件和路径监视器,当被监视的文件或路径发生修改、添加和删除等变化时会发送相应的信号,被监视的文件和路径一般不超过 256 个。
用 QFileSystemWatcher
定义文件监视器对象的方法如下所示:
QFileSystemWatcher(parent:QObject=None)
QFileSystemWatcher(paths:Sequence[str], parent:QObject=None)
其中 parent
是继承自 QObject
类的实例对象;paths
是 字符串列表,是 被监视的文件或路径。
QFileSystemWatcher
类常用方法:
addPath(file:str) -> bool # 添加被监视的路径或文件,成功返回True
addPaths(files:Sequence[str]) -> List[str] # 添加被监视的路径或文件,返回没有添加成功的路径和文件列表
directories() -> List[str] # 获取被监视的路径列表
files() -> List[str] # 获取被监视的文件列表
removePath(file:str) -> bool # 将被监视的路径或文件从监视中移除,成功返回True
removePaths(files:Sequcence[str]) -> List[str] # 移除被监视的路径或文件,返回没有移除成功的路径和文件列表
QFileSystemWatcher
类常用信号:
directoryChanged(path:str) # 当被监视的路径发生改变时发射信号
fileChanged(path:str) # 当被监视的文件发生改变时发射信号
用 addPath(file:str)
方法或 addPaths(files:Sequence[str])
方法 添加被监视的路径或文件。用 removePath(file:str)
方法或 removePaths(files:Sequence[str])
方法 移除被监视的文件或路径。用 directories()
方法 获取被监视的路径列表。用 files()
方法 获取被监视的文件列表。当被监视的路径发生改变(增加和删除文件及路径)或文件发生改变(修改、重命名、删除)时,会分别发送 directoryChanged(path)
信号和 fileChanged(fileName)
信号。