Qt on Android - 解决QFile关闭文件后立即断电,文件丢失,数据未保存问题
现象使用QFile类写数据到文件后,调用close()方法关闭并保存文件。之后设备立即断电,重启后发现该文件并未成功保存,文件里的数据仍是以前的数据。经检查,打开、写入都是成功的。  原因Linux/Unix系统中,在文件或数据处理过程中一般先放到内存缓冲区中,等到适当的时候再写入磁盘,以提高系统的运行效率。因此如果调用close
·
现象
使用QFile类写数据到文件后,调用close()方法关闭并保存文件。
之后设备立即断电,重启后发现该文件并未成功保存,文件里的数据仍是以前的数据。
经检查,打开、写入都是成功的。
原因
Linux/Unix系统中,在文件或数据处理过程中一般先放到内存缓冲区中,等到适当的时候再写入磁盘,以提高系统的运行效率。
因此如果调用close()方法后设备立即断电,会产生实际数据并未保存在硬盘中的现象。
解决过程中遇到的问题
经查Qt帮助文档,发现QFile的父类QFileDevice有一个方法:flush()
bool QFileDevice::flush()
Flushes any buffered data to the file. Returns true if successful; otherwise returns false.
看说明是将缓存的数据写入到文件的意思。
因此尝试在close()之前先flush()。
但经测试后发现并不可靠,还是利用Linux的系统函数fsync(int fd)来解决吧。
fsync
同步内存中所有已修改的文件数据到储存设备。
头文件
#include <unistd.h>
函数原型
int fsync(int fd);
解决方法
创建一个QFile的子类,重写close()函数,在close()之前调用系统函数fsync()将数据保存到硬盘。在程序中的文件操作用该子类完成即可。
lfile.h
#ifndef LFILE_H
#define LFILE_H
#include <QFile>
class LFile : public QFile
{
Q_OBJECT
public:
LFile(QObject *parent = nullptr);
LFile(const QString &name, QObject *parent = nullptr);
virtual void close();
};
#endif // LFILE_H
lfile.cpp
#include "lfile.h"
#include <unistd.h>
LFile::LFile(QObject *parent) : QFile(parent)
{
}
LFile::LFile(const QString &name, QObject *parent) : QFile(name, parent)
{
}
void LFile::close()
{
int fd = handle();
fsync(fd);
QFile::close();
}
更多推荐
已为社区贡献1条内容
所有评论(0)