由于该类中包含有纯虚函数,故不能实例化;只能派生重写;常见的QFile,QTcpSocket就是派生自它;
QIODevice区分两种类型的设备:随机访问设备和顺序访问设备。
随机访问设备支持seek函数,当前位置可通过pos获取;
顺序访问设备不支持定位到任意位置,故不能使用pos,size等;
使用 isSequential() 决定设备数据那种类型;
1. 常见接口
打开设备并设置打开模式为mode;成功返回true;
(1) bool open(OpenMode mode);
enum OpenModeFlag {
NotOpen = 0x0000, //设备未打开
ReadOnly = 0x0001,//可读打开
//可写打开,除非和ReadOnly,Append,NewOnly联合使用,否则内容将被清空!!!
WriteOnly = 0x0002,
ReadWrite = ReadOnly | WriteOnly, //可读写打开
Append = 0x0004, //追加模式打开,写将会从末尾开始;
Truncate = 0x0008, //打开并清空内容
//当读取时,行结束符被转换为'\n';当写时,行结束符将被转换为本地编码;如win32的'\r\n';
Text = 0x0010,
Unbuffered = 0x0020,//设备中的任何缓冲区都将被绕过。
/*如果要打开的文件已经存在,则失败。仅在文件不存在时创建并打开该文件。
操作系统保证您是唯一一个创建和打开文件的人。请注意,该模式意味着只写,
并且允许将其与读写相结合。该标志目前只影响QFile。将来其他类可能会使用这个标志,
但在此之前,将该标志用于QFile以外的任何类可能会导致未定义的行为。(因为Qt 5.11)*/
NewOnly = 0x0040,
/*如果要打开的文件不存在,则失败。该标志必须与ReadOnly、WriteOnly或ReadWrite一起指定。
注意,只使用这个标志和ReadOnly是多余的,因为当文件不存在时ReadOnly已经失败了。
该标志目前只影响QFile。将来其他类可能会使用这个标志,但在此之前,
将该标志用于QFile以外的任何类可能会导致未定义的行为。(因为Qt 5.11)*/
ExistingOnly = 0x0080
};
Q_DECLARE_FLAGS(OpenMode, OpenModeFlag)
示例:
QFile file(QString("/opt/test.txt"));
if(!file.open(QIODevice::ReadOnly | QIODevice::Text )){
return;//打开失败
}
首先发送aboutToClose()信号,关闭设备并设置打开的模式为NotOpen,错误字符串被复位;
(2) void close();
示例:
file.close();
文件打开模式至少为ReadOnly!
从设备读最大maxlen字节,存入data中;返回实际读到的大小;
(3) qint64 read(char *data, qint64 maxlen);
从设备读最大maxlen字节
(4) QByteArray read(qint64 maxlen);
读出所有内容
(5) QByteArray readAll();
读一行,最多读maxlen字节,存入data中,返回实际读数量
(6) qint64 readLine(char *data, qint64 maxlen);
读取一行
(7) QByteArray readLine(qint64 maxlen = 0);
readLine示例: 加入文件第一行数据为: hello=1
(a) QByteArray byte = file.readLine(6);
qDebug() << byte << "ret= " << byte.size() << endl;//"hello" ret= 5
(b) QByteArray byte = file.readLine();
qDebug() << byte << "ret= " << byte.size() << endl;//"hello=1\n" ret= 8
(c) qint64 ret = file.readLine(data, 6);
qDebug() << data << "ret= " << ret << endl;//hello ret= 5
(d) char data[1024];
qint64 ret = file.readLine(data, 1024);
qDebug() << data << "ret= " << ret << endl;
/* 打印
hello=1
ret= 8
*/
(e) QByteArray byte = file.readLine();
QString qs = QString(byte);
QStringList list = qs.split('=');
qDebug() << list.at(0);
//qDebug() << list.at(1);//"1\n"
qDebug() << list.at(1).toInt() ;//1
文件打开模式至少为WriteOnly!
写最大len字节data数据到设备;返回实际写的数据长度;
(8) qint64 write(const char *data, qint64 len);
将数据从以'\0'结束的8位字符字符串写入设备。
(9) qint64 write(const char *data);
将byteArray的内容写入设备。返回实际写入的字节数;
(10) qint64 write(const QByteArray &data);
示例:
file.write("world");
file.write("i love china",5);
QString s("linux");
file.seek(20); //配合seek定位不同位置;
ile.write(s.toUtf8());
若读或写位置在设备的末尾返回true;
(11) bool atEnd() const;
示例:
while(!file.atEnd())
{
file.readLine();
//...
}
对于随机访问设备,可设置当前位置为pos
(12) bool seek(qint64 pos);
seek到随机接入设备的输入开始。成功返回true;
(13) bool reset();
从设备跳转到maxSize字节。返回实际跳过的字节数,
(14) qint64 skip(qint64 maxSize);
从设备读取最多maxSize字节到数据,没有副作用;
(15) qint64 peek(char *data, qint64 maxlen);
示例:
bool isExeFile(QFile *file) //判断该文件是否时可执行问文件,.exe开始两字节为MZ;
{
char buf[2];
if (file->peek(buf, sizeof(buf)) == sizeof(buf))
return (buf[0] == 'M' && buf[1] == 'Z');
return false;
}
从设备读取最多maxSize字节
(16) QByteArray peek(qint64 maxlen);
示例:
bool isExeFile(QFile *file)
{
return file->peek(2) == "MZ";
}
返回可用于读取的字节数。
(17) qint64 QIODevice::bytesAvailable() const;
重新实现这个函数的子类必须调用基实现,以便包含QIODevice缓冲区的大小。
qint64 CustomDevice::bytesAvailable() const
{
return buffer.size() + QIODevice::bytesAvailable();
}
判断文件是否已经打开,true表示已打开;
(18) bool isOpen() const;
如果可以从设备读取数据则返回true;和open时打开模式(ReadOnly)相关;
(19) bool QIODevice::isReadable() const;
若设备时顺序设备返回true;
(20) bool isSequential() const;
2. 信号
该信号在设备当前读取通道中每次有新的数据可用时发出。它只会在有新数据可用时再次发出,
例如当新的网络数据负载到达您的网络套接字时,或者当一个新的数据块被附加到您的设备时。
void readyRead();
当有新数据可从设备读取时,就会发出这个信号。channel参数设置为数据到达的读通道的索引。
与readyRead不同,无论当前的读通道是什么,它都会被发出。
void channelReadyRead(int channel);
该信号在每次将数据负载写入设备当前的写通道时发出。bytes参数设置为在此有效负载中写入的字节数。
不会递归发出
void bytesWritten(qint64 bytes);
该信号在每次将数据有效负载写入设备时发出。bytes参数设置为在此有效负载中写入的字节数,
而channel是写入这些字节的通道。与bytesWritten()不同的是,无论当前的写通道是什么,
它都会被触发。
void channelBytesWritten(int channel, qint64 bytes);
该信号在设备即将关闭时发出。若你想关闭设备前操作可连接此信号;
void aboutToClose();
当该设备的输入(读取)流关闭时,发出该信号。一旦检测到关闭,它就会被发出,这意味着仍然有数据
可用来使用read()读取。
void readChannelFinished();