QFile类我我们提供了操作文件的常用功能。它是一种io设备,可以用来读写文本文件和二进制文件,也可以用来读写Qt的资源文件。QFile类可以单独使用,该类本身提供了read/write函数,但更方便的方式是,将QFile和QTextStream或QDataStream一起使用。

一般情况下,使用QFile创建对象时,就会把要操作的文件名传递给它。但该类也提供了一个setFileName() 方法,允许我们在任何时候为QFile对象设置要操作的文件名。但是,QFile 只支持"/",不支持"\"。

在构造QFile的对象后,我们可以使用exists() 判断文件是否存在,使用remove() 删除一个文件。在进行实际的内容读写前,需调用open()打开文件,读写结束后,要调用close()关闭文件,也可以写调用一下flush(),冲刷缓冲区。就向我们刚才说的,我们一般使用QDataStream或QTextStream 读写文件,但我们也可以使用QFile继承自QIODevice的函数,如read()、readLine()、readAll()、write()等。除了读写函数外,我们还能使用size() 函数获得文件的大小;使用pos() 或 seek() 函数获取及设置文件读写的位置;使用atEnd() 函数判断是否到达了文件结尾。

直接使用QFile读写文件

QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;

while (!file.atEnd()) {
QByteArray line = file.readLine();
process_line(line);
}
在此,我们将QIODevice::Text传给了open()函数,该标志是用来告诉Qt将文件中的换行符由"\r\n",转换成"\n"。因为,默认情况下,QFile把文件当做二进制进行读写,不会进行任何的字节转换。
使用流读取文件:

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。默认情况下,QTextStream假定文件使用的是用户系统的本地8bit编码。我们也可以使用QTextStream::setCodec() 函数还改变这种行为。
当使用QFile,QFileInfo和QDir类去操作文件系统时,你可以使用Unicode编码的文件名。在Unix平台上,这些文件名会被转换成8-bit编码。但如果你想使用标准c++ API或者平台特定的API去访问文件,那么你可以使用encodeName() 和 decodeName() 函数在Unicode文件名和8-bit文件名之间进行转换。

在Unix平台下,存在一些特殊的系统文件,例如/proc目录下,对这个文件调用size() 总是返回0,然而,你还是能够从此类文件中读取到数据;这些数据是为了相应你的read() 函数而间接产生出来的。但是,在这种情况下,你不能使用atEnd() 来判断是否还有数据可读(因为atEnd() 对于大小为0的文件返回true)。相反,你应该调用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继承的open() 函数外,QFile本身也为我们提供了两个open() 函数:

bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags = DontCloseHandle)
bool open(int fd, OpenMode mode, FileHandleFlags handleFlags = DontCloseHandle)

第一个open() 会按一定的模式打开一个现存的文件指针。同时,可以再指定额外的标志。如下代码所示:
#include <stdio.h>

void printError(const char* msg)
{
QFile file;
file.open(stderr, QIODevice::WriteOnly);
file.write(msg, qstrlen(msg)); // write to stderr
file.close();
}
当一个QFile已这种方式打开时,那么后续的close() 函数的作用会受到AutoCloseHandle标志的影响。如果指定了该标志,并且这个open() 函数调用成功了,那么后续再QFile对象上调用close() 会关闭底层文件句柄。否则,若没指定这个标志,close()函数不会真正的关闭底层文件句柄,而只是冲刷 了一下缓冲区。如下测试代码所示:
#include <QCoreApplication>
#include <QFile>
#include <cstdio>

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

FILE *pf = fopen("test.txt", "wb");
if(pf == nullptr)
return 0;
QFile file;
file.open(pf, QIODevice::WriteOnly); //1
//file.open(pf, QIODevice::WriteOnly, QFileDevice::AutoCloseHandle); //2
file.write("hello");
file.close();
fwrite("world", strlen("world"), 1, pf);

return a.exec();
}
当我们使用 1处的方式打开文件指针,即不指定AutoCloseHandle标志,则close() 函数后的“world”是可以继续被写入文件的;若使用2处的方式打开文件指针,则“world”并不会再被写入文件,因为底层文件已关闭。

第二个open() 函数与此类似,只不过其是按一定模式打开一个现存的文件描述符。AutoCloseHandle标志也会影响后续的close()函数。同时,如果QFile已这种方式打开,那么它会被自动地设置为raw mode,这意味着文件的输入、输出函数的执行会变慢。如果你遇到了性能问题,你应该尝试使用其他的打开函数。

至于其他的成员函数,比如文件的删除、重命名,文件访问权限的设置,Qt的帮助文档已讲的很清除,大家可以在使用时随时查看即可。
---------------------
作者:求道玉
来源:CSDN
原文:https://blog.csdn.net/Amnes1a/article/details/65434670
版权声明:本文为博主原创文章,转载请附上博文链接!

使用QFile进行文件操作(QFile可以使用FILE *指针,还必须指定AutoCloseHandle)的更多相关文章

  1. Qt之文件操作 QFile

    原地址:http://blog.csdn.net/liuhongwei123888/article/details/6084761 今天学习QT的文件操作 1.QIODevice直接继承自QObjec ...

  2. 14、Java文件操作stream、File、IO

    1.文件操作涉及到的基本概念 File File类 是文件操作的主要对象中文意义就是 文件 顾名思意 万物皆文件,在计算上看到的所有东西都是文件保存,不管是你的图片.视频.数据库数据等等都是按照基本的 ...

  3. C#文件操作基础之File类和FileInfo类

    文件和I/O流的差异: 文件是一些具有永久存储及特定顺序的字节组成的一个有序的.具有名称的集合. 因此对于文件,我们经常想到文件夹路径,磁盘存储,文件和文件夹名等方面. I/O流提供一种后备存储写入字 ...

  4. 【java】文件操作java.io.File

    package 文件操作; import java.io.File; import java.io.IOException; public class TestFile { public static ...

  5. Java文件操作二:File文件的方法

    一.文件的判断方法 判断方法 .boolean canExecute()判断文件是否可执行 .boolean canRead()判断文件是否可读 .boolean canWrite() 判断文件是否可 ...

  6. AIR文件操作:使用文件对象操作文件和目录 .

    来源:http://blog.csdn.net/zdingxin/article/details/6635376 在AIR中可以方便的对本地文件操作,不过上次做了个项目,发现还是有不少不方便的地方,比 ...

  7. properties文件操作

    properties文件操作类 可以使用java.util.Properties读取.properties文件中的内容 import java.io.InputStream; import java. ...

  8. python 历险记(三)— python 的常用文件操作

    目录 前言 文件 什么是文件? 如何在 python 中打开文件? python 文件对象有哪些属性? 如何读文件? read() readline() 如何写文件? 如何操作文件和目录? 强大的 o ...

  9. AIR文件操作(二):使用文件对象操作文件和目录

    转载于:http://www.flashj.cn/wp/air-file-operation2.html 文件对象是啥?文件对象(File对象)是在文件系统中指向文件或目录的指针.由于安全原因,只在A ...

随机推荐

  1. 自己动手制作更好用的markdown编辑器-02

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im 文章目录 1. 工具条 1.1. 样式 1.2. 工具条截图 2. 状态栏消息 3. 文件 ...

  2. Redis命令学习-string类型操作

    APPEND key value     假设key已经存在,而且为字符串.那么这个命令会把value追加到原来值的末尾.假设key不存在.首先创建一个空字符串,再运行追加操作.     返回值:返回 ...

  3. java包命名规则

    package indi/onem.发起者名.项目名.模块名... package pers.个人名.项目名.模块名... package priv.个人名.项目名.模块名... package te ...

  4. openWRT自学---针对backfire版本的主要目录和文件的作用的分析整理

    特别说明:要编译backfire版本,一定要通过svn下载:svn co svn://svn.openwrt.org/openwrt/branches/backfire,而不能使用http://dow ...

  5. 解决PHP编译cURL的reinstall the libcurl问题

    今天正好要用到PHP的curl功能,发现服务器上的PHP并没有配置curl,进而查询PHP官方文档,得知编译PHP时需要带上 –with-curl参数,才能把curl模块编译进去.我现在PHP已经编译 ...

  6. Spring Data Redis 2.x 中 RedisConfiguration 类的新编写方法

    在 Spring Data Redis 1.x 的时候,我们可能会在项目中编写这样一个RedisConfig类: @Configuration @EnableCaching public class ...

  7. 基于JS实现回到页面顶部的五种写法(从实现到增强)

    这篇文章主要介绍了基于JS实现回到页面顶部的五种写法(从实现到增强)的相关资料,本文介绍的非常详细,实用性也非常高,非常具有参考借鉴价值,需要的朋友可以参考下   写法 [1]锚点 使用锚点链接是一种 ...

  8. 【Python + ATX基于uiautomator2】之编写unittest自动化测试脚本

    不说废话上代码: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/08/31 09:43 # @Author : zc # @ ...

  9. 008android初级篇之jni中数组的传递

    008android初级篇之jni中数组的传递 jni中在native中数据类型的实际类型 jchar 占两个字节,跟native c中的char(占一个字节)是两个数据类型 jbyte, unsig ...

  10. JavaScript中trim 方法实现

    Java中的 String 类有个trim() 能够删除字符串前后的空格字符.jQuery中也有trim()方法能够删除字符变量前后的字符串. 可是JavaScript中却没有对应的trim() 方法 ...