声明
#include <QCryptographicHash>
#include <QDebug>
#include <QDir>
#include <QDirIterator>
#include <QFile>
#include <QTextStream>
#include <QVector>
class FileUtils {
public:
static bool CopyDirectory(const QString& fromDir, const QString& toDir, bool bReplace = false);
static bool CopyFiles(const QStringList fromFile, const QString toDir);
static bool WriteLinesToFile(QFile& file, const QVector<QString>& vecFileContent);
static void GetSpecificFormatFilePath(const QString& dir, const QStringList& nameFilters, QFileInfoList& fileInfoList);
static void GetSpecificFormatFilePath(QString dir, QStringList& fileList, QString filter = "*.*");
static bool DelSpecificFormatFile(const QString& dir, const QStringList& nameFilters);
static bool DelEmptyDir(const QString& dir);
static bool DelEmptyDirInDir(const QString& dir);
static QString GetFileMd5(const QString& fileName);
static bool ReplaceFile(const QString& strOldFile, const QString& strNewFile);
static QString GetFileSize(qint64 size);
};
实现
1. 拷贝文件夹至指定目录
/**
* @brief 拷贝文件夹,bRet为true则替换目标文件,删除原文件
*
* @author
* @date 2021-02-21
*/
bool FileUtils::CopyDirectory(const QString& fromDir, const QString& toDir, bool bReplace)
{
QDir sourceDir(fromDir);
QDir targetDir(toDir);
if (!sourceDir.exists()) {
return false;
}
if (!targetDir.exists()) {
if (!targetDir.mkdir(targetDir.absolutePath()))
return false;
}
bool bRet = true;
QFileInfoList fileInfoList = sourceDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::DirsLast);
foreach (QFileInfo fileInfo, fileInfoList) {
if (fileInfo.isDir()) {
if (!CopyDirectory(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()), bReplace)) {
bRet = false;
}
} else {
//目标文件不存在
if (!targetDir.exists(fileInfo.fileName())) {
if (!QFile::copy(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()))) {
bRet = false;
continue;
}
//删除原文件
if (bReplace) {
if (!QFile::remove(fileInfo.filePath())) {
bRet = false;
continue;
}
}
} else if (bReplace) {
//目标文件存在,且需要替换
if (!ReplaceFile(targetDir.filePath(fileInfo.fileName()), fileInfo.filePath())) {
bRet = false;
continue;
}
}
}
}
return bRet;
}
2.拷贝文件至指定目录
/**
* @brief 将文件拷贝到指定目录
*
* @author
* @date 2021-02-21
*/
bool FileUtils::CopyFiles(const QStringList fromFile, const QString toDir)
{
if (fromFile.isEmpty()) {
return false;
}
QDir targetDir(toDir);
if (!targetDir.exists()) {
if (!targetDir.mkpath(targetDir.absolutePath()))
return false;
}
bool bRet = true;
for (const QString& file : fromFile) {
QFileInfo fileInfo(file);
if (!fileInfo.exists()) {
bRet = false;
continue;
}
if (!QFile::copy(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()))) {
bRet = false;
continue;
}
}
return bRet;
}
3.以覆盖方式,将内容按行写入文件
/**
* @brief 以覆盖方式,将内容按行写入文件
*
* @author
* @date 2021-02-21
*/
bool FileUtils::WriteLinesToFile(QFile& file, const QVector<QString>& vecFileContent)
{
bool bRet = true;
do {
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
//以覆盖方式打开失败
bRet = false;
break;
}
QTextStream qWriteStream(&file);
for (auto iter = vecFileContent.begin(); iter < vecFileContent.end(); iter++) {
qWriteStream << *iter << "\n";
}
file.close();
} while (0);
if (file.isOpen()) {
file.close();
}
return bRet;
}
4.递归获取指定文件夹下特定后缀的文件
/**
* @brief 递归获取指定文件夹下特定后缀的文件
*
* @author
* @date 2021-02-21
*/
void FileUtils::GetSpecificFormatFilePath(const QString& dir, const QStringList& nameFilters, QFileInfoList& fileInfoList)
{
QDir tarDir(dir);
QFileInfoList fileList = tarDir.entryInfoList(nameFilters);
QFileInfoList dirList = tarDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
foreach (QFileInfo fileInfo, dirList) {
QString dirPath = fileInfo.absoluteFilePath();
GetSpecificFormatFilePath(dirPath, nameFilters, fileInfoList);
}
foreach (QFileInfo fileInfo, fileList) {
fileInfoList.push_back(fileInfo);
}
}
5.从指定的文件夹中获取所有文件列表
/**
* @brief 从指定的文件夹中获取所有文件列表
*
* @author
* @date 2021-02-21
* @param dir 指定的文件夹路径
* @param fileList 所有文件列表
*/
void FileUtils::GetSpecificFormatFilePath(QString path, QStringList& fileList, QString filter)
{
QDir dir(path);
if (!dir.exists()) {
return;
}
//获取所选文件类型过滤器
QStringList filters;
filters << filter;
//定义迭代器并设置过滤器
QDirIterator dirIterator(path,
filters,
QDir::Files | QDir::NoSymLinks,
QDirIterator::Subdirectories);
while (dirIterator.hasNext()) {
dirIterator.next();
QFileInfo fileInfo = dirIterator.fileInfo();
fileList.append(fileInfo.absoluteFilePath());
}
}
6.删除指定文件夹下特定后缀的文件
/**
* @brief 删除指定文件夹下特定后缀的文件
*
* @author
* @date 2021-02-21
* @param dir 指定的文件夹路径
* @param fileList 所有文件列表
*/
bool FileUtils::DelSpecificFormatFile(const QString& dir, const QStringList& nameFilters)
{
bool bRet = true;
do {
QFileInfoList fileInfoList;
GetSpecificFormatFilePath(dir, nameFilters, fileInfoList);
foreach (QFileInfo fileInfo, fileInfoList) {
if (!QFile::remove(fileInfo.filePath())) {
bRet = false;
}
}
} while (0);
return bRet;
}
7.递归删除指定文件夹下所有空文件夹(包括指定文件夹)
bool FileUtils::DelEmptyDir(const QString& dir)
{
QDir targetDir(dir);
if (!targetDir.exists()) {
return false;
}
QFileInfoList FileInfoList = targetDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
bool bRet = true;
foreach (QFileInfo fileInfo, FileInfoList) {
if (fileInfo.isDir()) {
if (!DelEmptyDir(fileInfo.filePath())) {
bRet = false;
}
}
}
if (targetDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot).count() == 0) {
if (!targetDir.removeRecursively()) {
bRet = false;
}
}
return bRet;
}
8.递归删除指定文件夹下所有空文件夹(不包括指定文件夹)
bool FileUtils::DelEmptyDirInDir(const QString& dir)
{
bool bRet = true;
QDir targetDir(dir);
QFileInfoList dirList = targetDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
foreach (QFileInfo dirInfo, dirList) {
if (!FileUtils::DelEmptyDir(dirInfo.filePath())) {
bRet = false;
}
}
return bRet;
}
9.获取文件md5
QString FileUtils::GetFileMd5(const QString& fileName)
{
QFile f(fileName);
QString strMd5 = "";
if (f.open(QFile::ReadOnly)) {
QCryptographicHash hash(QCryptographicHash::Md5);
if (hash.addData(&f)) {
strMd5 = hash.result().toHex();
}
}
f.close();
return strMd5;
}
10.替换文件
bool FileUtils::ReplaceFile(const QString& strOldFile, const QString& strNewFile)
{
bool bRet = false;
do {
//现有文件改名为.bak
if (QFile::exists(strOldFile)) {
if (!QFile::rename(strOldFile, strOldFile + ".bak")) {
break;
}
}
//移动新的文件到策略目录下
if (!QFile::rename(strNewFile, strOldFile)) {
//移动失败,把.bak恢复为原文件
if (QFile::exists(strOldFile + ".bak")) {
if (!QFile::rename(strOldFile + ".bak", strOldFile)) {
//恢复失败
}
}
break;
}
//删除.bak
if (QFile::exists(strOldFile + ".bak")) {
if (!QFile::remove(strOldFile + ".bak")) {
//
}
}
bRet = true;
} while (0);
return bRet;
}
11.获得文件大小(包含单位)
QString FileUtils::GetFileSize(qint64 size)
{
char unit = 'B';
qint64 curSize = size;
if (curSize > 1024) {
curSize /= 1024;
unit = 'K';
if (curSize > 1024) {
curSize /= 1024;
unit = 'M';
if (curSize > 1024) {
curSize /= 1024;
unit = 'G';
}
}
}
return QString("%0%1").arg(curSize).arg(unit);
}