QIODevice Class
QIODevice 类是 Qt 中所有 I/O 设备的基接口类。更多内容...
| 头文件: | #include <QIODevice> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake: | QT += core |
| 继承自: | QObject 以及QIODeviceBase |
| 被继承者: | QAbstractSocket、QBluetoothSocket 、QBuffer 、QCoapReply 、QFileDevice 、QLocalSocket 、QNetworkReply 、QProcess ,以及QSerialPort |
- 所有成员的列表,包括继承的成员
- QIODevice 属于“输入/输出与网络”类。
注意:该类中的所有函数均为可重入的。
公共函数
| QIODevice() | |
| QIODevice(QObject *parent) | |
| virtual | ~QIODevice() |
| virtual bool | atEnd() const |
| virtual qint64 | bytesAvailable() const |
| virtual qint64 | bytesToWrite() const |
| virtual bool | canReadLine() const |
| virtual void | close() |
| void | commitTransaction() |
| int | currentReadChannel() const |
| int | currentWriteChannel() const |
| QString | errorString() const |
| bool | getChar(char *c) |
| bool | isOpen() const |
| bool | isReadable() const |
| virtual bool | isSequential() const |
| bool | isTextModeEnabled() const |
| bool | isTransactionStarted() const |
| bool | isWritable() const |
| virtual bool | open(QIODeviceBase::OpenMode mode) |
| QIODeviceBase::OpenMode | openMode() const |
| qint64 | peek(char *data, qint64 maxSize) |
| QByteArray | peek(qint64 maxSize) |
| virtual qint64 | pos() const |
| bool | putChar(char c) |
| qint64 | read(char *data, qint64 maxSize) |
| QByteArray | read(qint64 maxSize) |
| QByteArray | readAll() |
| int | readChannelCount() const |
| qint64 | readLine(char *data, qint64 maxSize) |
| QByteArray | readLine(qint64 maxSize = 0) |
(since 6.9) QByteArrayView | readLineInto(QSpan<char> buffer) |
(since 6.9) QByteArrayView | readLineInto(QSpan<std::byte> buffer) |
(since 6.9) QByteArrayView | readLineInto(QSpan<uchar> buffer) |
(since 6.9) bool | readLineInto(QByteArray *line, qint64 maxSize = 0) |
| virtual bool | reset() |
| void | rollbackTransaction() |
| virtual bool | seek(qint64 pos) |
| void | setCurrentReadChannel(int channel) |
| void | setCurrentWriteChannel(int channel) |
| void | setTextModeEnabled(bool enabled) |
| virtual qint64 | size() const |
| qint64 | skip(qint64 maxSize) |
| void | startTransaction() |
| void | ungetChar(char c) |
| virtual bool | waitForBytesWritten(int msecs) |
| virtual bool | waitForReadyRead(int msecs) |
| qint64 | write(const char *data, qint64 maxSize) |
| qint64 | write(const QByteArray &data) |
| qint64 | write(const char *data) |
| int | writeChannelCount() const |
信号
| void | aboutToClose() |
| void | bytesWritten(qint64 bytes) |
| void | channelBytesWritten(int channel, qint64 bytes) |
| void | channelReadyRead(int channel) |
| void | readChannelFinished() |
| void | readyRead() |
受保护函数
| virtual qint64 | readData(char *data, qint64 maxSize) = 0 |
| virtual qint64 | readLineData(char *data, qint64 maxSize) |
| void | setErrorString(const QString &str) |
| void | setOpenMode(QIODeviceBase::OpenMode openMode) |
(since 6.0) virtual qint64 | skipData(qint64 maxSize) |
| virtual qint64 | writeData(const char *data, qint64 maxSize) = 0 |
详细说明
QIODevice 为支持数据块读写(例如QFile 、QBuffer 和QTcpSocket )的设备提供了通用实现和抽象接口。QIODevice 是抽象类,无法实例化,但通常使用它定义的接口来提供与设备无关的 I/O 功能。 例如,Qt XML 类以 QIODevice 指针为操作对象,因此可与各种设备(如文件和缓冲区)配合使用。
在访问设备之前,必须调用open() 来设置正确的 OpenMode(例如 ReadOnly 或 ReadWrite)。然后,您可以使用write() 或putChar() 向设备写入数据,并通过调用read()、readLine() 或readAll() 进行读取。当您完成对设备的操作后,请调用close()。
QIODevice 将设备分为两类:随机访问设备和顺序访问设备。
- 随机访问设备支持使用seek() 跳转到任意位置。通过调用pos() 可获取文件中的当前位置。QFile 和QBuffer 就是随机访问设备的示例。
- 顺序设备不支持定位到任意位置。数据必须一次性读取完毕。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 线程)调用这些函数,可能会导致用户界面冻结。示例:
QProcess gzip;
gzip.start("gzip", QStringList() << "-c");
if (!gzip.waitForStarted())
return false;
gzip.write("uncompressed data");
QByteArray compressed;
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 允许您通过向 `open()` 传递 `Unbuffered` 标志来绕过任何缓冲机制。在继承 QIODevice 时,请务必注意:当设备以无缓冲模式打开时,需绕过您可能使用的任何缓冲机制。
通常,来自异步设备的传入数据流是碎片化的,数据块可能会在任意时间点到达。为处理数据结构的不完整读取,请使用 QIODevice 实现的事务机制。更多详细信息请参阅startTransaction() 及相关函数。
某些顺序设备支持通过多个通道进行通信。这些通道代表独立的数据流,具有独立序列化传输的特性。设备打开后,可通过调用readChannelCount() 和writeChannelCount() 函数来确定通道数量。要在通道之间切换,请分别调用setCurrentReadChannel() 和setCurrentWriteChannel()。 QIODevice 还提供了额外的信号,用于按通道处理异步通信。
安全性注意事项
QIODevice 提供了一组支持无限制读取的方法。在撰写本文时,这些方法包括readAll() 、readLine(0) 和readLineInto(buffer, 0) ——其中后两个方法对值0 具有特殊含义,将其视为无限制。
对于顺序设备,或者对于那些报告其size() 结果为零的设备(例如/dev/urandom ),只要有新数据可用,这些方法就会分块读取数据,并将数据追加到内部或用户提供的缓冲区中。这可能会导致内存不足的情况。 因此,建议避免在处理不可信输入或大小未知的输入时使用这些方法,并始终为读取操作提供合理的上限。
另请参阅 QBuffer 、QFile 以及QTcpSocket 。
成员函数文档
QIODevice::QIODevice()
创建一个 QIODevice 对象。
[explicit] QIODevice::QIODevice(QObject *parent)
使用给定的parent 构建一个QIODevice对象。
[virtual noexcept] QIODevice::~QIODevice()
该析构函数是虚拟的,且QIODevice 是一个抽象基类。该析构函数不会调用close(),但子类的析构函数可能会调用。如有疑问,请在销毁QIODevice 之前调用close()。
[signal] void QIODevice::aboutToClose()
当设备即将关闭时,会发出此信号。如果您需要在设备关闭前执行某些操作(例如,需要将单独缓冲区中的数据写入设备),请连接此信号。
[virtual] bool QIODevice::atEnd() const
如果当前的读写位置位于设备末尾(即设备上已无可用数据可读),则返回true ;否则返回false 。
对于某些设备,即使还有数据可读,atEnd() 仍可能返回 true。此特殊情况仅适用于那些会直接响应您调用read() 而生成数据的设备(例如,Unix 和 macOS 上的/dev 或/proc 文件,或所有平台上的控制台输入 /stdin )。
另请参阅 bytesAvailable()、read() 和isSequential()。
[virtual] qint64 QIODevice::bytesAvailable() const
返回可供读取的字节数。该函数通常与顺序设备配合使用,用于在读取前确定应在缓冲区中分配多少字节。
重写此函数的子类必须调用基类的实现,以便包含 `QIODevice` 缓冲区的大小。示例:
另请参阅 bytesToWrite()、readyRead() 和isSequential()。
[virtual] qint64 QIODevice::bytesToWrite() const
对于带缓冲的设备,该函数返回待写入的字节数。对于不带缓冲的设备,该函数返回 0。
重写此函数的子类必须调用基类的实现,以便将 `QIODevice` 的缓冲区大小包含在内。
另请参阅 bytesAvailable()、bytesWritten() 和isSequential()。
[signal] void QIODevice::bytesWritten(qint64 bytes)
每当向设备的当前写入通道写入一组数据时,都会触发此信号。bytes 参数的值即为该数据组中写入的字节数。
bytesWritten() 不会递归触发;若在连接了 bytesWritten() 信号的槽(slot)内部重新进入事件循环或调用waitForBytesWritten(),该信号将不会再次触发(尽管waitForBytesWritten() 仍可能返回 true)。
另请参阅 readyRead()。
[virtual] bool QIODevice::canReadLine() const
如果能从设备读取完整的一行数据,则返回true ;否则返回false 。
请注意,无缓冲设备无法确定可读取的内容,因此始终返回 false。
该函数通常与readyRead()信号配合使用。
重写此函数的子类必须调用基类的实现,以便包含QIODevice 缓冲区中的内容。示例:
bool CustomDevice::canReadLine() const
{
return buffer.contains('\n') || QIODevice::canReadLine();
}[signal] void QIODevice::channelBytesWritten(int channel, qint64 bytes)
每当向设备写入数据负载时,都会触发此信号。bytes 参数设置为该负载中写入的字节数,而channel 则表示数据写入的目标通道。与bytesWritten()不同,无论current write channel 如何,该信号都会被触发。
channelBytesWritten() 可以递归地触发——即使针对同一个通道也是如此。
另请参阅 bytesWritten() 和channelReadyRead()。
[signal] void QIODevice::channelReadyRead(int channel)
当设备上有新数据可供读取时,会发出此信号。channel 参数被设置为数据到达的读取通道的索引。与readyRead()不同,无论current read channel 设置为何值,该信号都会被触发。
channelReadyRead() 可以递归触发——即使针对同一个通道也是如此。
另请参阅 readyRead() 和channelBytesWritten()。
[virtual] void QIODevice::close()
首先发出aboutToClose(),然后关闭设备并将该设备的OpenMode设置为NotOpen。错误字符串也会被重置。
另请参阅 setOpenMode() 和QIODeviceBase::OpenMode 。
void QIODevice::commitTransaction()
完成一次读取事务。
对于顺序设备,事务期间记录在内部缓冲区中的所有数据都将被丢弃。
另请参阅 startTransaction() 和rollbackTransaction()。
int QIODevice::currentReadChannel() const
返回当前读取通道的索引。
另请参阅 setCurrentReadChannel()、readChannelCount() 以及QProcess 。
int QIODevice::currentWriteChannel() const
返回当前写入通道的索引。
另请参阅 setCurrentWriteChannel() 和writeChannelCount()。
QString QIODevice::errorString() const
返回最近发生的设备错误的通俗易懂的描述。
另请参阅 setErrorString()。
bool QIODevice::getChar(char *c)
从设备中读取一个字符,并将其存储在c 中。如果c 的值为nullptr ,则该字符将被丢弃。成功时返回true ;否则返回false 。
另请参阅 read()、putChar() 和ungetChar()。
bool QIODevice::isOpen() const
如果设备已打开,则返回true ;否则返回false 。如果可以从设备读取和/或向设备写入,则该设备处于打开状态。默认情况下,如果openMode()返回NotOpen ,则该函数返回false 。
另请参阅 openMode() 和QIODeviceBase::OpenMode 。
bool QIODevice::isReadable() const
如果能从设备中读取数据,则返回true ;否则返回false。使用bytesAvailable()来确定可读取的字节数。
这是一个便捷函数,用于检查设备的 OpenMode 是否包含 ReadOnly 标志。
[virtual] bool QIODevice::isSequential() const
如果该设备是顺序设备,则返回true ;否则返回false。
与随机访问设备不同,顺序设备没有起始、结束、大小或当前位置的概念,也不支持定位操作。 只有当设备报告有可用数据时,才能从该设备读取数据。顺序设备的最常见例子是网络套接字。在 Unix 系统中,诸如 /dev/zero 和 FIFO 管道之类的特殊文件属于顺序设备。
另一方面,普通文件则支持随机访问。它们既有大小属性,也有当前位置,并且支持在数据流中向前和向后寻址。普通文件属于非顺序设备。
另请参阅 bytesAvailable()。
bool QIODevice::isTextModeEnabled() const
如果启用了Text 标志,则返回true ;否则返回false 。
另请参阅 setTextModeEnabled()。
bool QIODevice::isTransactionStarted() const
如果设备上正在进行交易,则返回true ;否则返回false 。
另请参阅 startTransaction()。
bool QIODevice::isWritable() const
如果可以向设备写入数据,则返回true ;否则返回false。
这是一个便利函数,用于检查设备的 OpenMode 是否包含 WriteOnly 标志。
[virtual] bool QIODevice::open(QIODeviceBase::OpenMode mode)
打开设备并将设备的 OpenMode 设置为mode 。成功时返回true ;否则返回false 。应从 open() 的任何重写版本或其他用于打开设备的函数中调用此函数。
另请参阅 openMode() 和QIODeviceBase::OpenMode 。
QIODeviceBase::OpenMode QIODevice::openMode() const
返回设备被打开时的模式;即 ReadOnly 或 WriteOnly。
另请参阅 setOpenMode() 和OpenMode 。
qint64 QIODevice::peek(char *data, qint64 maxSize)
从设备中最多读取maxSize 字节数据到data 中,且不产生副作用(即,如果在调用peek()之后再调用read(),将获得相同的数据)。返回已读取的字节数。如果发生错误(例如,尝试读取以WriteOnly模式打开的设备),该函数将返回-1。
当没有更多数据可供读取时,返回 0。
示例:
bool isExeFile(QFile *file)
{
char buf[2];
if (file->peek(buf, sizeof(buf)) == sizeof(buf))
return (buf[0] == 'M' && buf[1] == 'Z');
return false;
}另请参阅 read()。
QByteArray QIODevice::peek(qint64 maxSize)
最多从设备中读取maxSize 字节的数据,并将读取到的数据作为QByteArray 返回。
示例:
bool isExeFile(QFile *file)
{
return file->peek(2) == "MZ";
}该函数无法报告错误;返回一个空的QByteArray 可能意味着当前没有可预览的数据,也可能表示发生了错误。
这是一个重载函数。
另请参阅 read()。
[virtual] qint64 QIODevice::pos() const
对于随机访问设备,该函数返回数据的写入或读取位置。对于顺序设备或已关闭的设备(这些设备不存在“当前位置”的概念),则返回 0。
设备的当前读写位置由QIODevice 在内部维护,因此无需重写此函数。在继承QIODevice 时,请使用QIODevice::seek()向QIODevice 通知设备位置的变化。
另请参阅 isSequential() 和seek()。
bool QIODevice::putChar(char c)
将字符c 写入设备。成功时返回true ;否则返回false 。
另请参阅 write()、getChar() 和ungetChar()。
qint64 QIODevice::read(char *data, qint64 maxSize)
从设备中读取最多maxSize 字节的数据到data 中,并返回已读取的字节数。如果发生错误(例如尝试从以WriteOnly模式打开的设备中读取数据),该函数将返回-1。
当没有更多数据可读时,该函数返回 0。但是,超出流末尾进行读取会被视为错误,因此在此类情况下该函数返回 -1(即在已关闭的套接字上读取,或在进程终止后读取)。
另请参阅 readData()、readLine() 和write()。
QByteArray QIODevice::read(qint64 maxSize)
从设备中读取最多maxSize 字节的数据,并将读取到的数据作为QByteArray 返回。
该函数无法报告错误;返回一个空的QByteArray 可能意味着当前没有可读取的数据,也可能意味着发生了错误。
这是一个重载函数。
QByteArray QIODevice::readAll()
从设备中读取所有剩余数据,并将其作为字节数组返回。
该函数无法报告错误;返回一个空的QByteArray 可能意味着当前没有可读取的数据,也可能表示发生了错误。此外,该函数也无法指示可能还有更多数据但未能读取。
int QIODevice::readChannelCount() const
如果设备已打开,则返回可用读取通道的数量;否则返回 0。
另请参阅 writeChannelCount() 和QProcess 。
[signal] void QIODevice::readChannelFinished()
当该设备中的输入(读取)流被关闭时,会触发此信号。该信号会在检测到关闭操作的瞬间立即触发,这意味着可能仍有数据可通过 `read()` 读取。
[pure virtual protected] qint64 QIODevice::readData(char *data, qint64 maxSize)
从设备中读取最多maxSize 字节的数据到data 中,并返回读取的字节数;若发生错误,则返回-1。
如果没有可读取的字节,且未来也不可能有更多字节可用(例如套接字已关闭、管道已关闭、子进程已结束),则该函数返回 -1。
此函数由QIODevice 调用。在创建QIODevice 的子类时,请重写此函数。
重写此函数时,务必确保该函数在返回前读取所有所需数据。这是为了确保QDataStream 能够对该类进行操作。QDataStream 假设所有请求的信息均已读取,因此若出现问题,它不会重试读取。
该函数可能被调用时传入的 maxSize 值为 0,这可用于执行读取后的操作。
另请参阅 read()、readLine(),以及writeData()。
qint64 QIODevice::readLine(char *data, qint64 maxSize)
该函数从设备中读取一行ASCII字符,最多maxSize - 1字节,将字符存储在data 中,并返回读取的字节数。 如果无法读取一行但未发生错误,该函数返回 0。如果发生错误,该函数返回实际读取的数据长度;若未读取任何数据,则返回 -1。
data 末尾总是附加一个结束字节“\0 ”,因此maxSize 必须大于 1。
数据将持续读取,直至满足以下任一条件:
- 读取到第一个“\n ”字符。
- maxSize - 读取了 1 字节。
- 检测到设备数据的结尾。
例如,以下代码从文件中读取一行字符:
QFile file("box.txt");
if (file.open(QFile::ReadOnly)) {
char buf[1024];
qint64 lineLength = file.readLine(buf, sizeof(buf));
if (lineLength != -1) {
// the line is available in buf
}
}缓冲区中包含换行符('\n')。如果在读取 maxSize - 1 字节之前未遇到换行符,则不会将换行符插入到缓冲区中。
注意:换行符 转换(例如,将\r 转换为\n )仅在通过 QIODevice::Text 标志以读取模式打开设备时才会执行。
请注意,在顺序设备上,数据可能无法立即获取,这可能会导致返回不完整的行。通过在读取前调用canReadLine() 函数,您可以检查是否可以读取完整的行(包括换行符)。
该函数会调用readLineData(),该函数是通过反复调用getChar()实现的。您可以通过在自己的子类中重写readLineData()来提供更高效的实现。
另请参阅 getChar()、read()、canReadLine() 以及write()。
QByteArray QIODevice::readLine(qint64 maxSize = 0)
从设备中读取一行数据,但不超过maxSize 个字符,并将结果作为字节数组返回。
如果maxSize 为 0 或未指定,则行长度不限,从而支持无限读取。
结果行可能带有尾随的行结束字符(“\n ” 或 “\r\n ”),因此可能需要调用QByteArray::trimmed()。
该函数无法报告错误;返回空的QByteArray 可能意味着当前没有可读取的数据,也可能意味着发生了错误。
这是一个重载函数。
[virtual protected] qint64 QIODevice::readLineData(char *data, qint64 maxSize)
从data 中读取最多maxSize 个字符,并返回读取的字符数。
该函数由readLine() 调用,并使用getChar() 提供其基础实现。缓冲设备可以通过重写此函数来提高readLine() 的性能。
readLine() 会向data 末尾追加一个 '\0' 字节;而 readLineData() 则无需执行此操作。
如果您重写此函数,请务必返回正确的值:它应返回本行读取的字节数(包括结尾的换行符),或者如果此时没有行可读,则返回 0。如果发生错误,仅当未读取任何字节时,才应返回 -1。 读取超过 EOF 被视为错误。
[since 6.9] QByteArrayView QIODevice::readLineInto(QSpan<char> buffer)
[since 6.9] QByteArrayView QIODevice::readLineInto(QSpan<std::byte> buffer)
[since 6.9] QByteArrayView QIODevice::readLineInto(QSpan<uchar> buffer)
从该设备读取一行数据到buffer 中,并返回buffer 中包含所读取数据的子集。
如果buffer 的大小小于该行的长度,则仅读取并返回buffer 中能容纳的字符。 在这种情况下,再次调用readLineInto() 将检索该行的剩余部分。要确定是否已读取整行,首先检查设备是否为atEnd(),以防最后一行未以换行符结尾。如果不是atEnd(),则验证返回的视图是否以 '\n' 结尾。否则,需要再次调用readLineInto()。
生成的行可能包含尾随的行结束字符("\n" 或 "\r\n "),因此可能需要调用QByteArrayView::trimmed()。
如果发生错误,该函数将返回一个空的QByteArrayView 。否则,它将是buffer 的一个子片段。如果当前没有可读取的数据,或者设备处于atEnd() 状态,该函数将返回一个空的QByteArrayView 。
请注意,返回值不以空字符结尾。若需空字符结尾,可传入buffer.chopped(1) ,然后在buffer[result.size()] 处插入 '\0'。
这些函数在 Qt 6.9 中引入。
另请参阅 readLine()。
[since 6.9] bool QIODevice::readLineInto(QByteArray *line, qint64 maxSize = 0)
从设备读取一行数据,但长度不超过maxSize 个字符,并将该行作为字节数组存储在line 中。
注意: 即使line 的值为nullptr ,也会从该设备读取 一行数据。
如果maxSize 为 0 或未指定,则该行长度不限,从而允许无限读取。
生成的行可能带有尾随的行结束字符(“\n ” 或 “\r\n ”),因此可能需要调用QByteArray::trimmed()。
如果当前没有可读取的数据,或者发生错误,该函数将返回false 并将line 设置为empty 。否则,它将返回true 。
请注意,无论何种情况,调用前line 中的内容都会被丢弃,但其capacity()值绝不会被减少。
该函数在 Qt 6.9 中引入。
另请参阅 readAll()、readLine() 和QTextStream::readLineInto()。
[signal] void QIODevice::readyRead()
每当设备当前读取通道中有新数据可供读取时,该信号就会被触发一次。只有当有新数据可用时,该信号才会再次被触发,例如当网络套接字收到新的网络数据负载,或者设备末尾追加了新的数据块时。
readyRead() 不会递归触发;如果您在连接到 readyRead() 信号的槽内重新进入事件循环或调用waitForReadyRead(),该信号将不会再次触发(尽管waitForReadyRead() 仍可能返回 true)。
针对实现QIODevice 派生类的开发者的注意事项:当有新数据到达时,你应始终触发 readyRead()(不要仅仅因为缓冲区中仍有待读取的数据就触发它)。在其他情况下请勿触发 readyRead()。
另请参阅 bytesWritten()。
[virtual] bool QIODevice::reset()
用于查找随机访问设备的输入起始位置。成功时返回 true;否则返回false (例如,当设备未打开时)。
请注意,当在QFile 上使用QTextStream 时,若在QFile 上调用reset(),将不会得到预期的结果,因为QTextStream 会对文件进行缓冲。请改用QTextStream::seek()函数。
另请参阅 seek()。
void QIODevice::rollbackTransaction()
回滚一个读取事务。
将输入流恢复到调用startTransaction() 时的状态。当在提交事务之前检测到读取不完整时,通常使用此函数来回滚事务。
另请参阅 startTransaction() 和commitTransaction()。
[virtual] bool QIODevice::seek(qint64 pos)
对于随机访问设备,该函数将当前位置设置为pos ,成功时返回true,发生错误时返回false。对于顺序访问设备,默认行为是发出警告并返回false。
在继承QIODevice 时,必须在函数开头调用QIODevice::seek(),以确保与QIODevice 的内置缓冲区保持一致。
另请参阅 pos() 和isSequential()。
void QIODevice::setCurrentReadChannel(int channel)
将QIODevice 的当前读取通道设置为给定的channel 。当前输入通道被以下函数使用:read()、readAll()、readLine() 和getChar()。它还决定了哪个通道会触发QIODevice 来发出readyRead()信号。
另请参阅 currentReadChannel()、readChannelCount()、QProcess 。
void QIODevice::setCurrentWriteChannel(int channel)
将QIODevice 的当前写入通道设置为给定的channel 。当前输出通道由函数write()和putChar()使用。它还决定了哪个通道会触发QIODevice 发出bytesWritten()。
另请参阅 currentWriteChannel() 和writeChannelCount()。
[protected] void QIODevice::setErrorString(const QString &str)
将最近发生的设备错误的人类可读描述设置为str 。
另请参阅 errorString()。
[protected] void QIODevice::setOpenMode(QIODeviceBase::OpenMode openMode)
将设备的 OpenMode 设置为openMode 。如果设备打开后标志发生了变化,请调用此函数来设置打开模式。
void QIODevice::setTextModeEnabled(bool enabled)
如果enabled 为真,则该函数会在设备上设置Text 标志;否则,将清除Text 标志。此功能对于在QIODevice 上提供自定义换行符处理的类非常有用。
调用此函数前应先打开 IO 设备。
另请参阅 isTextModeEnabled()、open() 和setOpenMode()。
[virtual] qint64 QIODevice::size() const
对于已打开的随机访问设备,该函数返回设备的大小。对于已打开的顺序访问设备,该函数返回bytesAvailable()。
如果设备已关闭,返回的大小将无法反映设备的实际大小。
另请参阅 isSequential() 和pos()。
qint64 QIODevice::skip(qint64 maxSize)
从设备中跳过最多maxSize 字节的数据。返回实际跳过的字节数;若发生错误,则返回-1。
该函数不进行等待,仅丢弃已可供读取的数据。
如果设备以文本模式打开,行尾分隔符将被转换为 '\n' 符号,并被视为一个字节,其行为与read() 和peek() 完全一致。
该函数适用于所有设备,包括无法调用seek() 的顺序设备。它经过优化,可在调用peek() 后跳过不需要的数据。
对于随机访问设备,可使用 skip() 从当前位置向前寻址。不允许使用负数的maxSize 值。
另请参阅 skipData()、peek()、seek() 以及read()。
[virtual protected, since 6.0] qint64 QIODevice::skipData(qint64 maxSize)
从设备中跳过最多maxSize 字节的数据。返回实际跳过的字节数;若发生错误,则返回 -1。
该函数由QIODevice 调用。在创建QIODevice 的子类时,请考虑重写此函数。
基类实现通过将数据读入一个虚拟缓冲区来丢弃数据。这种方法虽然速度较慢,但适用于所有类型的设备。子类可以重写此函数以提升性能。
该函数于 Qt 6.0 中引入。
另请参阅 skip()、peek()、seek() 以及read()。
void QIODevice::startTransaction()
在设备上启动一个新的读取事务。
在读取操作序列中定义一个可恢复点。对于顺序设备,读取数据将在内部进行复制,以便在读取不完整时能够恢复。对于随机访问设备,此函数将保存当前位置。调用commitTransaction() 或rollbackTransaction() 来结束事务。
注意: 不支持嵌套 事务。
另请参阅 commitTransaction() 和rollbackTransaction()。
void QIODevice::ungetChar(char c)
将字符c 写回设备,并递减当前位置(除非当前位置为0)。通常调用此函数来“撤销”getChar()操作,例如在编写回溯解析器时。
如果c 此前未从设备中读取,则行为未定义。
注意: 在事务进行期间,此 函数不可用。
[virtual] bool QIODevice::waitForBytesWritten(int msecs)
对于带缓冲的设备,该函数会等待直到缓冲的写入数据已写入设备且已触发bytesWritten() 信号,或者直到经过msecs 毫秒。如果 msecs 为 -1,则该函数不会超时。对于不带缓冲的设备,该函数会立即返回。
如果已将数据有效载荷写入设备,则返回true ;否则返回false (即操作超时或发生错误时)。
该函数可在无事件循环的情况下运行。这在编写非GUI应用程序以及在非GUI线程中执行I/O操作时非常有用。
如果从连接到bytesWritten()信号的槽内调用,则不会再次发出bytesWritten()信号。
重写此函数以提供自定义设备的阻塞 API。默认实现不执行任何操作,并返回false 。
警告: 从主(GUI)线程调用 此函数可能会导致用户界面冻结。
另请参阅 waitForReadyRead()。
[virtual] bool QIODevice::waitForReadyRead(int msecs)
阻塞直至有新数据可供读取且已触发readyRead()信号,或者直到经过msecs 毫秒。如果msecs为-1,则该函数不会超时。
如果可读取新数据,则返回true ;否则返回 false(如果操作超时或发生错误)。
该函数可在无事件循环的情况下运行。这在编写非GUI应用程序以及在非GUI线程中执行I/O操作时非常有用。
如果从连接到readyRead()信号的槽内调用,readyRead()将不会被重新发出。
重写此函数可为自定义设备提供阻塞式 API。默认实现不执行任何操作,并返回 `false`。
警告: 从主(GUI)线程调用 此函数可能会导致用户界面冻结。
另请参阅 waitForBytesWritten()。
qint64 QIODevice::write(const char *data, qint64 maxSize)
从data 向设备写入最多maxSize 字节的数据。返回实际写入的字节数;若发生错误,则返回-1。
qint64 QIODevice::write(const QByteArray &data)
将data 中的内容写入设备。返回实际写入的字节数;如果发生错误,则返回-1。
这是一个重载函数。
qint64 QIODevice::write(const char *data)
将一个由8位字符组成的以零结尾的字符串写入设备。返回实际写入的字节数;如果发生错误,则返回-1。这等同于
...
QIODevice::write(data, qstrlen(data));
...这是一个重载函数。
int QIODevice::writeChannelCount() const
如果设备已打开,则返回可用写入通道的数量;否则返回 0。
另请参阅 readChannelCount()。
[pure virtual protected] qint64 QIODevice::writeData(const char *data, qint64 maxSize)
将data 中的最多maxSize 字节数据写入设备。返回已写入的字节数;若发生错误,则返回-1。
此函数由QIODevice 调用。在创建QIODevice 的子类时,请重写此函数。
重写此函数时,务必确保该函数在返回前写入所有可用数据。这是为了确保QDataStream 能够对该类进行操作。QDataStream 假定所有信息均已写入,因此若出现问题,它不会重试写入操作。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.