Qt:QFile、QIODevice
QFile
0、说明
QFile是读写文件的类,这里的文件包括文本文件、二进制文件、资源文件。
通常情况下,文件读写使用QFile、QTextStream、QDataStream就够了。
file name在构造QFile时传入,或者通过setFileName()自己设置。不管什么OS,QFile中的分隔符都是 '/'。其它分隔符均不支持。
通过exists()检查文件是否存在,用remove()移除文件(更多文件系统相关的操作可见QFileInfo and QDir.)
通过open()打开文件,close()关闭文件,flush()刷新文件。
文件中的数据通常用QDataStream or QTextStream读写,当然也可以直接调用从QIODevice继承下来的read()、readLine()、readAll()、write()进行读写。QFile也继承了getChar()、putChar()、ungetChar(),这些方法一次操作单个字符。
文件大小通过size()得到。当前访问到的数据所在文件中的位置通过pos()完成定位,移动到一个新的位置可以用seek()方法。如果移动到了文件末尾,atEnd()方法将返回true。
①直接读取文件
QFile file("in.txt");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    return;
while(!file.atEnd()){
    QByteArray line = file.readLine();
    process_line(line);
}
QIODevice::Text告诉Qt编译器,把Windows风格的行间隔符 \r\n 转换为 C++风格的 \n。默认情况下,QFile被认为是二进制文件,在读取过程中并不进行转换。
②使用Stream读取文件
QFile file("in.txt");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    return;
QTextStream in(&file);
while(!in.atEnd()){
    QString line = in.readLine();
    process_line(line);
}
QTextStream会把磁盘中的8bit 数据转换为16bit 的Unicode QString。默认情况下,编译器认为认为用户系统的编码方式为UTF-8,如果要修改编码方式,可以调用QTextStream::setCodec()。
③用Stream写入文件
如果要写入文本,我们可以用重载运算符 <<,运算符左侧是QTextStream对象,右侧可以是任意数据类型。
QFile file("out.txt");
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    return;
QTextStream out(&file);
out << "The magic number is: "<<49<<"\n";
如果用QDataStream读写,用法是相似的——我们可以用<<来write,用>>来read。具体用法可以查看QDataStream官方文档:QDataStream。
当我们使用QFile、QFileInfo、QDir来访问文件系统时,我们用的是Unicode文件名。在Unix中,这些文件名将被转换为UTF-8编码,如果我们想调用标准C++ API(如<cstdio>、<iostream>)去访问file而非QFile,我们可以用encodeName()和decodeName()在Unicode和UTF-8的file name间互相转换。
在Unix系统中,有些特殊的系统文件,它们的size()总返回0,但是我们仍能从中读取许多数据,这些数据在调用read()方法时获取。此时我们不能用atEnd()来判断是否读到了末尾,而只能用readAll()一次读完,或者重复用read()、readLine()直到没有数据可读。下一个例子中,我们用QTextStream按行读取/proc/modules文件:
QFile file("/proc/modules");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    return;
QTextStream in(&file);
QString line = in.readLine();
while( !line.isNull() ){
    process_line(line);
    line = in.readLine();
}
最后,需要注意的是QFile是继承自QIODevice的,而所有read、write的相关方法都是在QIODevice中定义的,所以具体的读写方法见QIODevice。
1、模块和加载项
| Header | #include<QFile> | 
| qmake | QT += core | 
| Inherits | QFileDevice | 
| Inherited By | QTemporaryFile | 
2、构造
| QFile(QString name, QObject *parent) | 
| QFile(QObject *parent) | 
| QFile(QString name) | 
| QFile() | 
3、实例方法
| 返回值类型 | 方法 | 说明 | 
| bool | copy(const QString &newName) | |
| bool | exists() | |
| bool | link(const QString &linkName) | |
| bool | moveToTrash() | |
| bool | open(FILE *fh, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle) | |
| bool | open(int fd, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle) | |
| bool | remove() | |
| bool | rename(const QString &newName) | |
| void | setFileName(const QString &name) | |
| QString | symLinkTarget() | 
4、静态方法
| 方法返回值 | 方法 | 说明 | 
| bool | copy(const QString &fileName, const QString &newName) | |
| QString | decodeName(const QByteArray &localFileName) | |
| QString | decodeName(const char *localFileName) | |
| QByteArray | encodeName(const QString &fileName) | |
| bool | exists(const QString &fileName) | |
| bool | link(const QString &fileName, const QString &linkName) | |
| bool | moveToTrash(const QString &fileName, QString *pathInTrash = nullptr) | |
| bool | permissions(const QString &fileName) | |
| bool | remove(const QString &fileName) | |
| bool | rename(const QString &oldName, const QString &newName) | |
| bool | resize(const QString &fileName, qint64 sz) | |
| bool | setPermissions(const QString &fileName, QFileDevice::Permissions permissions) | |
| QString | symLinkTarget(const QString &fileName) | 
QIODevice
0、说明
QIODevice中实现了Qt中的所有I/O方法,其他用到IO的类如QFile、QBuffer、QTcpSocket,都是从这个类继承而来。
QIODevice是抽象类,不能实例化,但是可以用多态技术,来定义一个QIODevice去承接一个从它继承而来的实现类。
在读写之前,open()一个文件时必须先设置正确的OpenMode(如ReadOnly或ReadWrite)。之后就可以调用write()、putChar()向其中write,调用read()、readLine()、readAll()来read。完成read、write后调用close()。
有两种Device:①随机访问;②顺序访问。
①随机访问:调用seek()转移到文件中任意位置,调用pos()查看当前位置。QFile、QBuffer是随机访问的典型;
②顺序访问:不能从任意位置开始。数据读取必须一个接一个。QTcpSocket、QProcess是顺序访问的典型。
如何判断是哪种device呢?调用isSequential()方法。
QIODevice会发射readyRead()当新的数据已经准备好reading,例如,读取的时候,有新的数据到达网络或额外的数据被添加到文件中。我们可以调用bytesAvailable()来判断现在有多少个bytes是准备读取的。当QTcpSocket程序处理异步数据时,经常会有数据不定时的到达,这时bytesAvailable()通常和readyRead()信号联用。当有数据要write时,QIODevice会发射bytesWritten()信号,此时用bytesToWrite()可以知道有多少bytes等待写入。
1、模块和加载项
| Header | #include<QIODevice> | 
| qmake | QT += core | 
| Inherits | QObject | 
| Inherited By | QFileDevice | 
2、构造
| QIODevice(QObject * parent) | 给Parent构造一个QIODevice | 
| QIODevice() | 构造一个QIODevice | 
3、静态属性
| 类型 | 属性 | 说明 | 
| flags | OpenMode | |
| enum | OpenModeFlag | 
这个enum是用于open()的参数,主要是描述文件打开时采用的device。如果要查看这个device,可以通过openMode()返回。
常用的Mode有ReadOnly、WriteOnly、ReadWrite、Append,对应的device顾名思义。
4、对象方法
| 返回值类型 | 方法 | 说明 | 
| virtual bool | atEnd() | 如果当前的read、write位置已经到了device末尾返回true,否则返回false。 在某些系统文件中,atEnd()总是返回false,这种文献的读写可见QFile的说明部分。 | 
| virtual qint64 | bytesAvailable() | 返回有多少bytes可被读取。常用于顺序读写。 | 
| virtual qint64 | bytesToWrite() | 用于buffer Device,该方法返回有多少bytes正等待write。对于没有buffer的Device,该方法返回0。 | 
| virtual bool | canReadLine() | 每当有完整的一行数据可以从device中读取时返回true,否则false。 对于非buffer Device,该方法返回false。 该方法常和信号readyRead()结合使用。 | 
| virtual void | close() | 先发送aboutToClose()信号,然后关闭Device并设置它的OpenMode为NotOpen。此外error string也会被重置。 | 
| void | commitTransaction() | 完成事务读取。 对于顺序Device,保存数据的内部buffer在事务期将被丢弃。 | 
| int | currentReadChannel() | 返回当前read channel的索引号 | 
| int | currentWriteChannel() | 返回当前write channel的索引号 | 
| QString | errorString() | 返回最后一次device error的描述 | 
| bool | getChar(char *c) | 读取单个char存到c中,成功时返回true,否则false | 
| bool | isOpen() | Device为非NotOpen时返回true,否则false; 如果有data可以从device中读取时返回true,否则false。常用于检查Device的Mode是否包含ReadOnly 当Device是顺序Device时返回true,否则false 当Text标记开启时返回true,否则false 如果某个事务正在处理,返回true,否则false 当有数据可以向Device中写入时返回true,常用于检查Mode是否包含WriteOnly。 | 
| virtual bool | open(QIODevice::OpenMode mode) | 打开Device并将它的OpenMode设置为mode。 QFile的open方法重载了它,并且可以同时指定打开文件和Mode | 
| QIODevice::OpenMode | openMode() | 返回当前Device的Mode,如ReadOnly或WriteOnly | 
| qint64 | peek(char *data, qint64 maxSize) | 从Device中读取最多maxSize bytes的数据到data中,并不会改变pos,即pos一直指向读取开始的位置。返回读取的bytes数。 发生错误时返回-1,没有可读数据时返回0。 | 
| QByteArray | peek(qint64 maxSize) | 从Device中读取至多maxSize bytes,返回读取到的数据,类型是QByteArray。 | 
| virtual qint64 | pos() | 随机访问时,返回当前读写到的文件位置。 对于顺序Device或者关闭的Device,返回0。 当前的 read/write位置会在QIODevice内部维护,所以重载该方法并不是必要的。 | 
| bool | putChar(char c) | 向Device中写入单个char,成功时返回true。 | 
| qint64 | read(char *data, qint64 maxSize) | 从Device中读取至多maxSize bytes到data中,返回读取到的bytes数量。错误发生时返回-1。 当没有数据可读时返回0。 | 
| QByteArray | read(qint64 maxSize) | 重载方法。 从Device中读取至多maxSize bytes,返回读取到的data对应的QByteArray。 发生错误时不报错,只是返回空QByteArray。 | 
| QByteArray | readAll() | 读取Device中所有剩余的数据,返回读到的data对应的QByteArray。 | 
| int | readChannelCount() | 当Device打开时,返回可用的read channel的数量。 | 
| qint64 | readLine(char *data, qint64 maxSize) | 从Device中读取一行ASCII字符,至多maxSize-1 bytes,保存读取到的数据到data中,返回读取到的bytes数。 无法读取时,返回0。发生错误时,返回可读的长度,如果长度为0返回-1。 每次读取都会在data后边加一个\0,所以maxSize必须大于1。 读到以下三种情况时结束: 
 例如,下面的代码显示了如何从一个文件中读取一行字符:     QFile file("box.txt");行结束符'\n'也会包含在buffer中。如果没有读完一行便到了maxSize - 1,那么该行便不会完整读入buffer。 | 
| QByteArray | readLine(qint64 maxSize = 0) | 读一行,但不超过maxSize个char,将读取结果以QByteArray形式返回 | 
| virtual bool | reset() | 重置pos到随机访问Device开头。 需要注意的是,当我们用QTextStream读取QFile,不能用reset()回到文件头,而应该用QTextStream::seek() | 
| void | rollbackTransaction() | 事务回滚。 恢复input stream到startTransaction()调用前。 该方法常用于在提交事务前检测到未完成read的时候。 | 
| virtual bool | seek(qint64 pos) | 用于随机方法Device,该方法重置当前位置到pos。 | 
| void | setCurrentReadChannel(int channel) | 设置当前QIODevice的read channel为给定的channel,当前的channel常被方法read()、readAll()、readLine()、getChar()调用。当前channel会激发QIODevice发送readyRead()信号。 | 
| void | setCurrentWriteChannel(int channel) | 设置当前QIODevice的write channel为给定的channel,当前的channel用于方法write()、putChar()。它会激发QIODevice发送bytesWritten()信号。 | 
| void | setTextModeEnabled(bool enabled) | 如果参数是true,该方法会给Device设置Text标志,否则Text标志会被移除。 该特性对于那些提供了行结尾处理方法的类很有帮助。 | 
| virtual qint64 | size() | 对于随机访问Device,该方法返回Device的大小。 对于顺序访问Device,该方法返回byteAvailable() | 
| qint64 | skip(qint64 maxSize) | 从文件开头跳转到maxSize bytes处。返回实际跳转的byte数,出错返回-1。 该方法可以应用到全部Device中,包括随机访问和顺序访问。 该方法常和peek()联合使用,跳过不需要的数据。 对于随机访问,它可以跳转到当前pos之前,负的maxSize是非法的。 | 
| void | startTransaction() | 在Device上开始一个新的read事务。 该方法会定义一个恢复点。在顺序Device中,数据会在内部备份以防止由于恢复导致的不完整的读取。 在随机Device,该方法存储当前pos。调用commitTransaction()、rollbackTransaction()来完成事务。 | 
| void | ungetChar(char c) | 把单个字符c放回Device中,并后移当前pos。 该方法常用于作为getChar()方法的"undo"方法。 | 
| virtual bool | waitForBytesWritten(int msecs) | |
| virtual bool | waitForReadyRead(int msecs) | |
| qint64 | write(char * data, qint64 maxSize) | 从data中写至多maxSize bytes到Device中,返回实际写入的bytes数。 发生错误时返回-1 | 
| qint64 | write(char * data) | 把data写入Device中,返回实际写入的bytes数。 | 
| qint64 | write(QByteArray byteArray) | 把byteArray的内容写到Device中,返回实际写入的bytes数。 | 
| int | writeChannelCount() | 当Device为open时返回可用的write channel数量,否则返回0 | 
5、信号
| 信号 | 说明 | 
| aboutToClose() | 当Device要关闭时发送该信号。 | 
| bytesWritten(qint64 bytes) | 当有数据已经写入Device的对应的write channel时发送该信号。 | 
| channelBytesWritten(int channel, qint64 bytes) | 当有数据已经写入Device中时发送该信号。 | 
| channelReadyRead(int channel) | 当有新数据要从Device中可读的时候发送该信号。 | 
| readChannelFinished() | 输入流关闭时发送该信号。 | 
| readyRead() | 当有新数据要从Device对应的read channel中可读的时候发送该信号。 | 
Qt:QFile、QIODevice的更多相关文章
- Qt:QList、QStringList
		QList 0.说明 QList<T> 一个QList是存储相同类型一组数据的列表. QStringList是从QList<String>继承而来,并添加了一些好用的方法,如j ... 
- QT:异常、错误
		1.Unknown module(s) in QT: xxx 原因1:我们的QT中没有安装这个Module 解决方法:Unknown module(s) 与MaintenanceTool.exe更新. ... 
- Qt:QDateTime、QDate、QTime与QDateTimeEdit
		时间日期是经常遇到的数据类型,Qt中的时间日期类如下: QTime:时间类型,只表示时间,如15:23:13: QDate:日期类型,只表示日期,如2017-4-5: QDateTime:日期时间类型 ... 
- QT:QString、QByteArray和char *的转换 【转载】
		原文网址:http://blog.csdn.net/light1028/article/details/7899541 第一种,数据流的方式,这里只说从QByteArray转向QString. QBy ... 
- QT文件(夹)操作---QFile、QDir、QFileInfo、QTextStream和QDataStream异同
		1.1 文件和目录 QFile.QBuffer和QTcpSocket可支持读写设备,用open函数打开,用write或putChar函数写入.用read和readLine或readAll进行读取 ... 
- Qt:QJsonDocument以及与QJsonArray、QJsonObject、QJsonValue的关联
		0.说明 QJsonDocument类提供了read/write JSON文档的方法. 用QJsonDocument::fromJson()方法,可以从将一个JSON文件(或者QByteArray数据 ... 
- Qt入门之基础篇 ( 二 ) :Qt项目建立、编译、运行和发布过程解析
		转载请注明出处:CN_Simo. 题解: 本篇内容主讲Qt应用从创建到发布的整个过程,旨在帮助读者能够快速走进Qt的世界. 本来计划是讲解Qt源码静态编译,如此的话读者可能并不能清楚地知道为何要静态编 ... 
- Qt 学习之路 2(42):QListWidget、QTreeWidget 和 QTableWidget
		Qt 学习之路 2(42):QListWidget.QTreeWidget 和 QTableWidget 豆子 2013年2月5日 Qt 学习之路 2 38条评论 上一章我们了解了 model/vie ... 
- Qt 学习之路 2(12):菜单栏、工具栏和状态栏
		Home / Qt 学习之路 2 / Qt 学习之路 2(12):菜单栏.工具栏和状态栏 Qt 学习之路 2(12):菜单栏.工具栏和状态栏 豆子 2012年9月10日 Qt 学习之路 2 2 ... 
随机推荐
- Python如何把八进制转换成ASCII码
			做题途中拿到一串八进制字符串 0126 062 0126 0163 0142 0103 0102 0153 0142 062 065 0154 0111 0121 0157 0113 0111 010 ... 
- Linux查看CPU历史负载
			sar -f /var/log/sa/sa20 -s 02:00:00 -e 06:00:00 | head -n 50 sysstat工具与负载历史回放 很多系统负载过高的时候我们是无法立即获知或者 ... 
- ORA-15081: failed to submit an I/O operation to a disk
			Problem: While restoring controlfile to test environment, from filesystem or tape environment after ... 
- Android安卓开发-记账本布局
			账单页面布局统计页面布局我的页面布局主页面加号记账页面布局.点击记账页面记账类别布局点击收入页面收入类别布局统计页面支出布局统计页面收入布局查询页面布局数据库设计字段一,支出id和收入id分配字段二, ... 
- 【C++】输入输出
			缓冲 C++ 的输入输出均通过缓冲区来实现.缓冲区主要是为了解决速度不匹配的问题. cin 阻塞输入.当输入缓存中无字符时则等待用户输入. 输入缓冲 输入缓冲是一种行缓冲.在输入数据只要没有碰到换行符 ... 
- JS 基本类型的包装对象
			笔记整理自:廖雪峰老师的JS教程 目录 包装对象 不写new的作用 总结 注意 包装对象 JavaScript还提供了包装对象,熟悉Java的小伙伴肯定很清楚int和Integer这种暧昧关系. nu ... 
- StringUtils.isBlank(str)和StringUtils.isEmpty(str)的区别
			1.StringUtils.isEmpty(CharSequence cs)实现源码 public static boolean isEmpty(CharSequence cs) { return c ... 
- 鸟哥的Linux学习笔记-bash
			1. /bin/bash是linux预设的shell,也是Linux发行版的标准shell,它兼容sh,可以看作是sh的功能加强. 2. bash具有命令记录功能,在bash中通过上下键就可以翻找之前 ... 
- LaunchScreen&LaunchImage
			优先级:LaunchScreen > LaunchImage 在xcode配置了,不起作用 1.清空xcode缓存 2.直接删掉程序 重新运行 如果是通过LaunchImage设置启动界面,那么 ... 
- 阿里云无法ping通解决
			https://blog.csdn.net/longgeaisisi/article/details/78429099 
