PySide6.QtCore.QIODevice

class QIODevice

QIODevice 类是 Qt 中所有 I/O 设备的基础接口类。更多

PySide6.QtCore.QIODevice 的继承图

继承自: QSerialPort, QNetworkReply, QLocalSocket, QAbstractSocket, QUdpSocket, QTcpSocket, QWaveDecoder, QProcess, QFileDevice, QSaveFile, QFile, QTemporaryFile, QSslSocket, QBuffer, QCoapReply, QCoapResourceDiscoveryReply, QBluetoothSocket

概要

方法

虚拟方法

信号

注意

本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对代码片段翻译的贡献。如果您发现翻译问题,您也可以通过在我们的https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。

详细描述

警告

本节包含从C++自动翻译到Python的代码片段,可能包含错误。

QIODevice 为支持数据块读写操作的设备提供了一个通用的实现和抽象接口,例如 QFileQBuffer 和 QTcpSocket。QIODevice 是抽象的,不能实例化,但通常使用它定义的接口来提供设备无关的I/O功能。例如,Qt 的 XML 类操作一个 QIODevice 指针,允许它们与各种设备(如文件和缓冲区)一起使用。

在访问设备之前,必须调用open()来设置正确的OpenMode(例如ReadOnly或ReadWrite)。然后,您可以使用write()putChar()写入设备,并通过调用read()readLine()readAll()来读取。当您完成设备操作时,请调用close()

QIODevice 区分两种类型的设备:随机访问设备和顺序设备。

  • 随机访问设备支持使用seek()定位到任意位置。通过调用pos()可以获取文件中的当前位置。QFileQBuffer是随机访问设备的示例。

  • 顺序设备不支持寻址到任意位置。数据必须一次性读取。函数 pos()size() 不适用于顺序设备。QTcpSocket 和 QProcess 是顺序设备的例子。

你可以使用isSequential()来确定设备的类型。

QIODevice 在有新数据可供读取时发出 readyRead();例如,如果网络上有新数据到达,或者如果正在读取的文件中附加了更多数据。您可以调用 bytesAvailable() 来确定当前可供读取的字节数。在使用异步设备(如 QTcpSocket)进行编程时,通常会结合使用 bytesAvailable()readyRead() 信号,因为数据片段可能会在任意时间点到达。QIODevice 每次将数据有效负载写入设备时都会发出 bytesWritten() 信号。使用 bytesToWrite() 来确定当前等待写入的数据量。

QIODevice 的某些子类,例如 QTcpSocket 和 QProcess,是异步的。这意味着像 write()read() 这样的 I/O 函数总是立即返回,而与设备本身的通信可能在控制返回到事件循环时发生。QIODevice 提供了允许你强制立即执行这些操作的函数,同时阻塞调用线程且不进入事件循环。这使得 QIODevice 子类可以在没有事件循环的情况下使用,或者在单独的线程中使用:

  • waitForReadyRead() - 此函数会暂停调用线程的操作,直到有新数据可供读取。

  • waitForBytesWritten() - 此函数会暂停调用线程的操作,直到一个数据负载被写入设备。

  • waitFor….() - QIODevice 的子类实现了设备特定操作的阻塞函数。例如,QProcess 有一个名为 waitForStarted() 的函数,它会暂停调用线程的操作,直到进程启动。

从主GUI线程调用这些函数可能会导致您的用户界面冻结。示例:

gzip = QProcess()
gzip.start("gzip", QStringList() << "-c")
if not gzip.waitForStarted():
    return False
gzip.write("uncompressed data")
compressed = QByteArray()
while gzip.waitForReadyRead():
    compressed += gzip.readAll()

通过子类化QIODevice,您可以为自己的I/O设备提供相同的接口。QIODevice的子类只需要实现受保护的readData()writeData()函数。QIODevice使用这些函数来实现其所有便捷功能,例如getChar()readLine()write()QIODevice还为您处理访问控制,因此您可以安全地假设如果调用了writeData(),设备将以写入模式打开。

一些子类,例如 QFile 和 QTcpSocket,使用内存缓冲区来实现数据的中间存储。这减少了所需的设备访问调用次数,这些调用通常非常慢。缓冲使得像 getChar()putChar() 这样的函数变得快速,因为它们可以在内存缓冲区上操作,而不是直接在设备本身上操作。然而,某些 I/O 操作与缓冲区不太兼容。例如,如果多个用户打开同一设备并逐个字符读取,他们可能会在打算读取各自的数据块时最终读取相同的数据。因此,QIODevice 允许您通过将 Unbuffered 标志传递给 open() 来绕过任何缓冲。在子类化 QIODevice 时,请记住在设备以 Unbuffered 模式打开时绕过您可能使用的任何缓冲区。

通常,来自异步设备的传入数据流是分段的,数据块可以在任意时间点到达。为了处理数据结构的不完整读取,请使用由QIODevice实现的事务机制。有关更多详细信息,请参阅startTransaction()及相关函数。

一些顺序设备支持通过多个通道进行通信。这些通道代表独立的数据流,具有独立排序传递的特性。一旦设备被打开,您可以通过调用readChannelCount()writeChannelCount()函数来确定通道的数量。要在通道之间切换,分别调用setCurrentReadChannel()setCurrentWriteChannel()QIODevice还提供了额外的信号来处理每个通道的异步通信。

另请参阅

QBuffer QFile QTcpSocket

__init__()

构造一个QIODevice对象。

__init__(parent)
Parameters:

父对象QObject

使用给定的parent构造一个QIODevice对象。

aboutToClose()

当设备即将关闭时,会发出此信号。如果您有需要在设备关闭之前执行的操作(例如,如果您有数据在单独的缓冲区中需要写入设备),请连接此信号。

atEnd()
Return type:

布尔

如果当前读写位置位于设备的末尾(即设备上没有更多数据可供读取),则返回true;否则返回false

对于某些设备,即使还有更多数据要读取,atEnd() 也可能返回 true。这种特殊情况仅适用于那些在你调用 read() 时直接生成数据的设备(例如,Unix 和 macOS 上的 /dev/proc 文件,或所有平台上的控制台输入 / stdin)。

bytesAvailable()
Return type:

整数

警告

本节包含从C++自动翻译到Python的代码片段,可能包含错误。

返回可用于读取的字节数。此函数通常与顺序设备一起使用,以确定在读取之前应在缓冲区中分配的字节数。

重新实现此函数的子类必须调用基类实现,以包含QIODevice缓冲区的大小。示例:

def bytesAvailable(self):

    return buffer.size() + QIODevice.bytesAvailable()
bytesToWrite()
Return type:

整数

对于有缓冲的设备,此函数返回等待写入的字节数。对于没有缓冲的设备,此函数返回0。

重新实现此函数的子类必须调用基类实现,以便包含QIODevice缓冲区的大小。

bytesWritten(bytes)
Parameters:

bytes – 整数

每次将数据有效负载写入设备的当前写入通道时,都会发出此信号。bytes参数设置为在此有效负载中写入的字节数。

bytesWritten() 不会递归地发出;如果你在连接到 bytesWritten() 信号的槽中重新进入事件循环或调用 waitForBytesWritten(),信号将不会重新发出(尽管 waitForBytesWritten() 可能仍然返回 true)。

另请参阅

readyRead()

canReadLine()
Return type:

布尔

警告

本节包含从C++自动翻译到Python的代码片段,可能包含错误。

如果可以从设备读取完整的数据行,则返回 true;否则返回 false

请注意,无法确定可读取内容的无缓冲设备总是返回false。

此函数通常与readyRead()信号一起调用。

重新实现此函数的子类必须调用基类实现,以便包含QIODevice缓冲区的内容。示例:

def canReadLine(self):

    return buffer.contains('\n') or QIODevice.canReadLine()

另请参阅

readyRead() readLine()

channelBytesWritten(channel, bytes)
Parameters:
  • channel – 整数

  • bytes – int

每次向设备写入数据负载时都会发出此信号。bytes参数设置为在此负载中写入的字节数,而channel是它们被写入的通道。与bytesWritten()不同,无论current write channel如何,都会发出此信号。

channelBytesWritten() 可以递归地发出 - 即使是对于同一个通道。

channelReadyRead(channel)
Parameters:

channel – 整数

当设备有新数据可供读取时,会发出此信号。channel参数设置为数据到达的读取通道的索引。与readyRead()不同,无论current read channel如何,都会发出此信号。

channelReadyRead() 可以递归地发出 - 即使是对于同一个通道。

close()

首先发出aboutToClose(),然后关闭设备并将其OpenMode设置为NotOpen。错误字符串也会被重置。

另请参阅

setOpenMode() OpenMode

commitTransaction()

完成一个读取事务。

对于顺序设备,事务期间记录在内部缓冲区中的所有数据将被丢弃。

currentReadChannel()
Return type:

整数

返回当前读取通道的索引。

currentWriteChannel()
Return type:

整数

返回当前写入通道的索引。

errorString()
Return type:

字符串

返回最近发生的设备错误的人类可读描述。

另请参阅

setErrorString()

getChar()
Return type:

布尔

从设备读取一个字符并将其存储在c中。如果cNone,则该字符将被丢弃。成功时返回true;否则返回false

isOpen()
Return type:

布尔

如果设备已打开,则返回true;否则返回false。如果设备可以读取和/或写入,则设备已打开。默认情况下,如果openMode()返回NotOpen,则此函数返回false

另请参阅

openMode() OpenMode

isReadable()
Return type:

布尔

如果可以从设备读取数据,则返回true;否则返回false。使用bytesAvailable()来确定可以读取多少字节。

这是一个便捷函数,用于检查设备的OpenMode是否包含ReadOnly标志。

另请参阅

openMode() OpenMode

isSequential()
Return type:

布尔

如果此设备是顺序的,则返回true;否则返回false。

顺序设备,与随机访问设备相反,没有开始、结束、大小或当前位置的概念,也不支持查找。只有当设备报告有数据可用时,你才能从中读取数据。最常见的顺序设备示例是网络套接字。在Unix上,特殊文件如/dev/zero和fifo管道是顺序的。

另一方面,常规文件确实支持随机访问。它们既有大小也有当前位置,并且还支持在数据流中前后查找。常规文件是非顺序的。

另请参阅

bytesAvailable()

isTextModeEnabled()
Return type:

布尔

如果启用了Text标志,则返回true;否则返回false

另请参阅

setTextModeEnabled()

isTransactionStarted()
Return type:

布尔

如果设备上有交易正在进行,则返回true,否则返回false

另请参阅

startTransaction()

isWritable()
Return type:

布尔

如果数据可以写入设备,则返回 true;否则返回 false。

这是一个便捷函数,用于检查设备的OpenMode是否包含WriteOnly标志。

另请参阅

openMode() OpenMode

open(mode)
Parameters:

modeOpenModeFlag 的组合

Return type:

布尔

打开设备并将其OpenMode设置为mode。如果成功,返回true;否则返回false。此函数应从任何重新实现的open()或其他打开设备的函数中调用。

另请参阅

openMode() OpenMode

openMode()
Return type:

OpenModeFlag 的组合

返回设备被打开的模式;即只读或只写。

另请参阅

setOpenMode() OpenMode

peek(maxlen)
Parameters:

maxlen – 整数

Return type:

QByteArray

警告

本节包含从C++自动翻译到Python的代码片段,可能包含错误。

这是一个重载函数。

窥视设备中最多 maxSize 字节的数据,返回窥视到的数据作为 QByteArray

示例:

def isExeFile(file):

    return file.peek(2) == "MZ"

此函数无法报告错误;返回一个空的QByteArray可能意味着当前没有可用的数据进行窥视,或者发生了错误。

另请参阅

read()

peek(buffer, maxlen)
Parameters:
  • bufferPyBuffer

  • maxlen – int

Return type:

整数

pos()
Return type:

整数

对于随机访问设备,此函数返回数据写入或读取的位置。对于顺序设备或关闭的设备,没有“当前位置”的概念,返回0。

设备的当前读写位置由QIODevice内部维护,因此不需要重新实现此函数。当子类化QIODevice时,使用seek()来通知QIODevice设备位置的变化。

另请参阅

isSequential() seek()

putChar(c)
Parameters:

c – 整数

Return type:

布尔

将字符 c 写入设备。成功时返回 true;否则返回 false

read(maxlen)
Parameters:

maxlen – 整数

Return type:

QByteArray

这是一个重载函数。

从设备中最多读取 maxSize 字节,并返回读取的数据作为 QByteArray

此函数无法报告错误;返回一个空的QByteArray可能意味着当前没有可读取的数据,或者发生了错误。

read(buffer, maxlen)
Parameters:
  • bufferPyBuffer

  • maxlen – int

Return type:

整数

readAll()
Return type:

QByteArray

从设备读取所有剩余数据,并将其作为字节数组返回。

此函数无法报告错误;返回一个空的QByteArray可能意味着当前没有可读取的数据,或者发生了错误。此函数也无法指示可能有更多数据可用但无法读取。

readChannelCount()
Return type:

整数

如果设备已打开,则返回可用的读取通道数;否则返回0。

readChannelFinished()

当此设备中的输入(读取)流关闭时,会发出此信号。一旦检测到关闭,就会立即发出信号,这意味着可能仍有数据可供使用read()读取。

另请参阅

atEnd() read()

abstract readData(maxlen)
Parameters:

maxlen – 整数

Return type:

PyObject

从设备读取最多 maxSize 字节到 data 中,并返回读取的字节数,如果发生错误则返回 -1。

如果没有字节可读,并且永远不会有更多字节可用(例如套接字关闭、管道关闭、子进程完成),此函数返回 -1。

此函数由QIODevice调用。在创建QIODevice的子类时,请重新实现此函数。

在重新实现此函数时,重要的是此函数在返回之前读取所有必需的数据。这是为了使QDataStream能够对该类进行操作所必需的。QDataStream假设所有请求的信息都已读取,因此如果出现问题,不会重试读取。

此函数可能会以0的maxSize调用,这可以用于执行读取后的操作。

readLine([maxlen=0])
Parameters:

maxlen – 整数

Return type:

QByteArray

这是一个重载函数。

从设备读取一行,但不超过maxSize个字符,并将结果作为字节数组返回。

如果maxSize为0或未指定,则该行的长度可以是任意的,从而实现无限读取。

结果行可能包含尾部的换行符(”\n” 或 “\r\n”),因此可能需要调用 trimmed()

此函数无法报告错误;返回一个空的QByteArray可能意味着当前没有可读取的数据,或者发生了错误。

readLine(buffer, maxlen)
Parameters:
  • bufferPyBuffer

  • maxlen – int

Return type:

整数

readLineData(maxlen)
Parameters:

maxlen – 整数

Return type:

PyObject

读取最多 maxSize 个字符到 data 中,并返回读取的字符数。

此函数由readLine()调用,并使用getChar()提供其基本实现。缓冲设备可以通过重新实现此函数来提高readLine()的性能。

readLine()data 后附加一个‘\0’字节;readLineData() 不需要这样做。

如果你重新实现这个函数,请注意返回正确的值:它应该返回此行读取的字节数,包括终止的换行符,或者如果没有行可读则返回0。如果发生错误,只有在没有读取任何字节的情况下才应返回-1。读取超过EOF被视为错误。

readyRead()

每当设备当前读取通道有新数据可供读取时,此信号就会发出一次。只有在有新数据可用时,例如当网络数据的新负载到达您的网络套接字时,或者当新数据块附加到您的设备时,它才会再次发出。

readyRead() 不会递归地发出;如果你在连接到 readyRead() 信号的槽中重新进入事件循环或调用 waitForReadyRead(),信号将不会重新发出(尽管 waitForReadyRead() 可能仍然返回 true)。

对于实现从QIODevice派生的类的开发者的注意事项:当新数据到达时,你应该总是发出readyRead()信号(不要仅仅因为缓冲区中仍有数据要读取而发出它)。在其他情况下不要发出readyRead()信号。

另请参阅

bytesWritten()

reset()
Return type:

布尔

尝试将随机访问设备的输入定位到起始位置。成功时返回true;否则返回false(例如,如果设备未打开)。

请注意,当在QFile上使用QTextStream时,调用QFile的reset()函数不会达到预期效果,因为QTextStream会缓冲文件。请改用seek()函数。

另请参阅

seek()

rollbackTransaction()

回滚一个读事务。

将输入流恢复到startTransaction()调用的点。此函数通常用于在检测到不完整读取后回滚事务,以防止提交事务。

seek(pos)
Parameters:

pos – 整数

Return type:

布尔

对于随机访问设备,此函数将当前位置设置为pos,成功时返回true,如果发生错误则返回false。对于顺序设备,默认行为是产生警告并返回false。

当子类化 QIODevice 时,你必须在函数的开头调用 QIODevice::seek(),以确保与 QIODevice 的内置缓冲区的完整性。

另请参阅

pos() isSequential()

setCurrentReadChannel(channel)
Parameters:

channel – 整数

QIODevice的当前读取通道设置为给定的channel。当前输入通道由函数read()readAll()readLine()getChar()使用。它还决定了哪个通道会触发QIODevice发出readyRead()

setCurrentWriteChannel(channel)
Parameters:

channel – 整数

QIODevice的当前写入通道设置为给定的channel。当前输出通道由函数write()putChar()使用。它还决定了哪个通道触发QIODevice发出bytesWritten()

setErrorString(errorString)
Parameters:

errorString – str

将最后发生的设备错误的人类可读描述设置为str

另请参阅

errorString()

setOpenMode(openMode)
Parameters:

openModeOpenModeFlag 的组合

将设备的OpenMode设置为openMode。如果在设备打开后标志发生变化,请调用此函数来设置打开模式。

另请参阅

openMode() OpenMode

setTextModeEnabled(enabled)
Parameters:

enabled – 布尔值

如果 enabled 为 true,此函数将在设备上设置 Text 标志;否则将移除 Text 标志。此功能对于在 QIODevice 上提供自定义行尾处理的类非常有用。

在调用此函数之前,应打开IO设备。

size()
Return type:

整数

对于开放的随机访问设备,此函数返回设备的大小。对于开放的顺序设备,返回bytesAvailable()

如果设备已关闭,返回的尺寸将不会反映设备的实际尺寸。

另请参阅

isSequential() pos()

skip(maxSize)
Parameters:

maxSize – int

Return type:

整数

跳过设备中的最多maxSize字节。返回实际跳过的字节数,或在错误时返回-1。

此函数不会等待,只会丢弃已经可供读取的数据。

如果设备以文本模式打开,行结束符会被转换为‘\n’符号,并且与read()peek()的行为相同,计为单个字节。

此函数适用于所有设备,包括无法seek()的顺序设备。它经过优化,可以在peek()调用后跳过不需要的数据。

对于随机访问设备,skip() 可用于从当前位置向前查找。不允许使用负的 maxSize 值。

skipData(maxSize)
Parameters:

maxSize – int

Return type:

整数

跳过设备中的最多maxSize字节。返回实际跳过的字节数,或在错误时返回-1。

此函数由QIODevice调用。在创建QIODevice的子类时,考虑重新实现它。

基础实现通过读取到一个虚拟缓冲区来丢弃数据。这种方法虽然慢,但适用于所有类型的设备。子类可以重新实现这个函数以改进这一点。

另请参阅

skip() peek() seek() read()

startTransaction()

在设备上启动一个新的读取事务。

定义读取操作序列中的一个可恢复点。对于顺序设备,读取的数据将在内部复制,以便在不完整读取的情况下进行恢复。对于随机访问设备,此函数保存当前位置。调用commitTransaction()rollbackTransaction()来完成事务。

注意

不支持嵌套事务。

ungetChar(c)
Parameters:

c – 整数

将字符 c 放回设备,并减少当前位置,除非位置为 0。此函数通常用于“撤销” getChar() 操作,例如在编写回溯解析器时。

如果之前没有从设备读取c,则行为未定义。

注意

此功能在事务进行时不可用。

waitForBytesWritten(msecs)
Parameters:

msecs – 整数

Return type:

布尔

对于缓冲设备,此函数会等待直到缓冲的写入数据有效载荷已被写入设备并且bytesWritten()信号已发出,或者直到msecs毫秒过去。如果msecs为-1,此函数将不会超时。对于非缓冲设备,它会立即返回。

如果数据有效载荷被写入设备,则返回true;否则返回false(即如果操作超时或发生错误)。

此函数可以在没有事件循环的情况下运行。它在编写非GUI应用程序和在非GUI线程中执行I/O操作时非常有用。

如果从连接到bytesWritten()信号的槽中调用,bytesWritten()将不会被重新发出。

重新实现此函数以提供自定义设备的阻塞API。默认实现不执行任何操作,并返回false

警告

从主(GUI)线程调用此函数可能会导致您的用户界面冻结。

另请参阅

waitForReadyRead()

waitForReadyRead(msecs)
Parameters:

msecs – 整数

Return type:

布尔

阻塞直到有新数据可供读取并且readyRead()信号已发出,或者直到msecs毫秒过去。如果msecs为-1,此函数将不会超时。

如果有新数据可供读取,则返回true;否则返回false(如果操作超时或发生错误)。

此函数可以在没有事件循环的情况下运行。它在编写非GUI应用程序和在非GUI线程中执行I/O操作时非常有用。

如果从连接到readyRead()信号的槽中调用,readyRead()将不会被重新发出。

重新实现此函数以提供自定义设备的阻塞API。默认实现不执行任何操作,并返回false

警告

从主(GUI)线程调用此函数可能会导致您的用户界面冻结。

另请参阅

waitForBytesWritten()

write(data)
Parameters:

数据QByteArray

Return type:

整数

这是一个重载函数。

data的内容写入设备。返回实际写入的字节数,如果发生错误则返回-1。

另请参阅

read() writeData()

writeChannelCount()
Return type:

整数

如果设备已打开,则返回可用的写入通道数量;否则返回0。

另请参阅

readChannelCount()

abstract writeData(data, len)
Parameters:
  • data – 字符串

  • len – int

Return type:

整数

data向设备写入最多maxSize字节的数据。返回写入的字节数,如果发生错误则返回-1。

此函数由QIODevice调用。在创建QIODevice的子类时,请重新实现此函数。

在重新实现此函数时,重要的是此函数在返回之前写入所有可用数据。这是为了使QDataStream能够在类上操作所必需的。QDataStream假设所有信息都已写入,因此如果出现问题,不会重试写入。

另请参阅

read() write()