C++/Qt 读写文件

6 篇文章 0 订阅
本文介绍了C++中使用fstream进行基础文本和二进制文件操作,以及Qt中QFile、QTextStream和QDataStream的文件打开、关闭、读取和写入方法,包括不同打开模式和自定义数据结构的序列化。
摘要由CSDN通过智能技术生成

之前写过两篇跟文件操作相关的博客,有兴趣也可以看一下:

C语言读写文件

Qt关于文件路径的处理

先讲一些关于基础文本文件和二进制文件的读写操作,后续将会整理C++/Qt关于ini、xml、json、xlsx相关文件的读写操作。

C++

相比于C语言使用FILE文件指针来实现文件操作,C++ 采用的是标准库中的fstream类来实现文件的打开、关闭、读取和写入。

引入头文件:

#include <fstream>

打开文件:

 explicit ifstream(const char* fileName, ios_base::openmode mode = ios_base::in);
 explicit ifstream(const string& fileName, ios_base::openmode mode = ios_base::in);

第一个参数表示文件名,第二个表示打开方式,关于打开方式有以下几种,以下是官方给出的定义说明:

 // 27.4.2.1.4  Type ios_base::openmode
    /**
     *  @brief This is a bitmask type.
     *
     *  @c @a _Ios_Openmode is implementation-defined, but it is valid to
     *  perform bitwise operations on these values and expect the Right
     *  Thing to happen.  Defined objects of type openmode are:
     *  - app
     *  - ate
     *  - binary
     *  - in
     *  - out
     *  - trunc
    */
    typedef _Ios_Openmode openmode;

    /// Seek to end before each write.
    static const openmode app =		_S_app;

    /// Open and seek to end immediately after opening.
    static const openmode ate =		_S_ate;

    /// Perform input and output in binary mode (as opposed to text mode).
    /// This is probably not what you think it is; see
    /// https://gcc.gnu.org/onlinedocs/libstdc++/manual/fstreams.html#std.io.filestreams.binary
    static const openmode binary =	_S_bin;

    /// Open for input.  Default for @c ifstream and fstream.
    static const openmode in =		_S_in;

    /// Open for output.  Default for @c ofstream and fstream.
    static const openmode out =		_S_out;

    /// Open for input.  Default for @c ofstream.
    static const openmode trunc =	_S_trunc;
ios::in以读取的方式打开文件
ios::out以写入的方式打开文件,如果文件不存在则会创建文件
ios::ate打开文件时定位到文件尾部
ios::app以追加的形式打开文件,写入的内容将会添加到文件末尾
ios::trunc打开文件时将清空文件原有的内容
ios::binary以二进制的方式打开文件

这些方式可以采用“|”组合使用,例如:

	fstream file;
	file.open("1.txt", ios::out | ios::app);

以写入的方式打开文件1.txt,写入的内容将会追加到文件末尾。 

关闭文件:

close()

读取文件示例:

fstream file;
	file.open("1.txt", ios::in);
	if (file.is_open()) {
		string line;
		while (getline(file, line)) {
			cout << line << endl;
		}
		file.close();
	}

只读方式打开文件1.txt,如果该文件存在则会逐行打印文件内容

 1.txt文件内容:

运行结果:

写文件示例:

	fstream file;
	file.open("1.dat", ios::out | ios::trunc);
	if (file.is_open()) {
		file << "123";
		file << endl;
		file << "456";
		file << endl;
		file.close();
	}

以写文件的方式打开文件1.dat并且会先清空文件原有内容,执行后文件内容为:

Qt

Qt关于文件的打开、关闭、读取、写入操作将会用QFile、QTextStream、QDataStream,其中QFile负责文件的打开与关闭操作,QTextStream和QDataStream将以文本数据流和二进制数据流的方式读写文件。

打开文件:

    bool open(OpenMode flags) override;
    bool open(FILE *f, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
    bool open(int fd, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);

​

也是需要指定文件的打开OpenMode,OpenMode有以下定义:

QIODevice::NotOpen

设备未打开

QIODevice::ReadOnly

只读形式打开

QIODevice::WriteOnly

写文件形式打开,文件不存在则会创建文件

QIODevice::ReadWrite

读写形式打开

QIODevice::Append

追加形式打开,写入内容将添加到文件尾

QIODevice::Truncate

截断形式打开,会清除文件原版内容

QIODevice::Text

文本形式打开,读取时,行结束符被翻译为'\n'。在写入时,行结束符被转换为本地编码,例如Win32中的'\r\n'

QIODevice::Unbuffered

无缓冲形式打开,设备中的任何缓冲区都被绕过

QIODevice::NewOnly

如果要打开的文件已经存在,则失败。仅在文件不存在时创建并打开该文件。操作系统保证您是唯一创建和打开文件的人。注意,此模式意味着WriteOnly,并且允许将其与ReadWrite结合使用。这个标志目前只影响QFile。其他类将来可能会使用此标志,但在此之前,对QFile以外的任何类使用此标志可能会导致未定义的行为(自Qt 5.11起)

QIODevice::ExistingOnly

如果要打开的文件不存在,则失败。此标志必须与ReadOnly, WriteOnly或ReadWrite一起指定。注意,单独对ReadOnly使用此标志是多余的,因为当文件不存在时,ReadOnly已经失败了。这个标志目前只影响QFile。其他类将来可能会使用此标志,但在此之前,对QFile以外的任何类使用此标志可能会导致未定义的行为(自Qt 5.11起)

这些也是可以使用“|”一起使用的。
关闭文件:

close()

QTextStream:

QTextStream以文本数据流的形式读写文件。

头文件:

#include <QTextStream>

读文件示例:

    QFile file("1.txt");
    if (file.open(QIODevice::ReadOnly)) {
        QTextStream in(&file);
        while (!in.atEnd())
        {
            qDebug()<<in.readLine();
        }
        file.close();
    }

以只读的形式打开1.txt文件,然后逐行打印文件内容。

写文件示例:

   QFile file("1.txt");    
   if (file.open(QIODevice::WriteOnly|QIODevice::Append)) {
        QTextStream out(&file);
        out<<"123aa";
        out<<endl;
        out<<"456aa";
        out<<endl;
        file.close();
    }

以写文件的形式打开,并且写入的内容会在文件末尾追加内容。
QDataStream:

QDataStream是以二进制数据流的形式进行文件的读写操作,用于将二进制数据到 QIODevice 的序列化。

头文件:

#include <QDataStream>

示例:

    QFile file("1.dat");
    if (file.open(QIODevice::WriteOnly|QIODevice::Truncate)) {
        QDataStream out(&file);
        out << QString("abc");
        out << (int)123;
        file.close();
    }

以写文件以及截断方式打开文件1.dat,依次写入字符串“abc”和int整形123,程序执行后用notepad++打开对应文件预览:

可以看到因为是二进制形式写入文件中所以是不支持预览的,但是用对应的QDataStream可以直接读取:

QFile file("1.dat");    
if (file.open(QIODevice::ReadOnly)) {
        QDataStream in(&file);
        int i;
        QString s;
        in>>s;
        in>>i;
        qDebug()<<i<<s;
        file.close();
}

运行结果:

将图片数据写入文件:

    QFile file("1.dat");
    QFile pic("1.png");
    if (file.open(QIODevice::WriteOnly|QIODevice::Truncate) && pic.open(QIODevice::ReadOnly)) {
        QDataStream out(&file);
        out << pic.fileName();
        out << pic.readAll();
        file.close();
    }

将图片文件1.png的文件名和文件数据写入到文件1.dat中 ,反正也可以读取对应图片数据生成对应图片文件:

    QFile file("1.dat");
    if (file.open(QIODevice::ReadOnly)) {
        QDataStream in(&file);
        QByteArray data;
        QString name;
        in>>name;
        in>>data;
        QPixmap pix;
        pix.loadFromData(data);
        pix.save(name);
        file.close();
    }

QDataStream读写自定义数据:

比如用DataStream实现自定义结构体数据的读写。

    struct MyStruct {
        int i;
        QString s;
        double d;
        friend QDataStream& operator <<(QDataStream &stream, const MyStruct &ms)
        {
            stream<<ms.i<<ms.s<<ms.d;
            return stream;
        }

        friend QDataStream& operator >>(QDataStream &stream, MyStruct &ms)
        {
            stream>>ms.i>>ms.s>>ms.d;
            return stream;
        }
    };

需要重载对应<<和>>操作符

    QFile file("1.dat");
    if (file.open(QIODevice::WriteOnly|QIODevice::Truncate)) {
        QDataStream out(&file);
        MyStruct my;
        my.i = 1;
        my.s = "a";
        my.d = 1.1;
        out<<my;
        file.close();
    }

读取:
 

    if (file.open(QIODevice::ReadOnly)) {
        QDataStream in(&file);
        MyStruct ms;
        in>>ms;
        qDebug()<<ms.i<<ms.s<<ms.d;
        file.close();
    }

运行效果:

 成功读取对应文件中的结构体数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值