之前写过一个QT自动识别文本文件的编码格式的博文,但是那是基于Qt5.15.2的,在Qt5下运行没有问题,今天改用Qt6.8后,就不行了老是报错,于是针对Qt6,又略微改进了一下。
示例代码:
//获取文件编码格式函数
QStringConverter::Encoding Skysonya::getFileCharacterEncoding(const QString &fileName)
{
//假定默认编码utf8
QStringConverter::Encoding encoding = QStringConverter::Utf8;
QString codecName = "UTF-8"; //为了显示qDebug用
QFile file(fileName);
if (file.open(QIODevice::ReadOnly))
{
QByteArray firstBytes = file.read(3);
// qDebug() << "FirstBytes:" << firstBytes << Qt::endl;
if (firstBytes.startsWith("\xEF\xBB\xBF"))
{
// UTF-8 with BOM
encoding = QStringConverter::Utf8;
codecName = "UTF-8-BOM";
}
else if (firstBytes.startsWith("\xFF\xFE"))
{
// UTF-16LE
encoding = QStringConverter::Utf16LE;
codecName = "UTF-16LE";
}
else if (firstBytes.startsWith("\xFE\xFF"))
{
// UTF-16BE
encoding = QStringConverter::Utf16BE;
codecName = "UTF-16BE";
}
else
{
// ANSI or UTF-8
QFile afile(fileName);
afile.open(QIODevice::ReadOnly);
QTextCodec::ConverterState converterState;
QTextCodec *textcodec =
QTextCodec::codecForName("utf-8"); //尝试用utf8转换,如果无效字符数大于0,则表示是ansi编码
int num{};
while (!afile.atEnd())
{
QByteArray line = afile.readLine(); //读取一行ASCII码
// qDebug() << "Line:" << line << Qt::endl;
textcodec->toUnicode(line.constData(), line.size(), &converterState);
num += converterState.invalidChars;
if (num > 0) break;
}
encoding = (num > 0) ? QStringConverter::System : QStringConverter::Utf8;
codecName = (num > 0) ? "GB18030" : "UTF-8";
}
qDebug() << "FileEncoding:" << encoding << codecName << Qt::endl;
file.close();
}
return encoding ;
}
具体使用:
//用QTextStream读取文件,整体读取
QString Skysonya::openFileByStreamWhole(const QString &fileName)
{
QFile file(fileName);
if (!file.exists())
{
messageBox("Warning", tr("打开"), "文件不存在: " + file.errorString());
return NULL;
}
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
messageBox("Warning", tr("打开"), "打开文件失败: " + file.errorString());
return NULL;
}
QTextStream textStream(&file); //用文本流读取文件内容
// textStream.setAutoDetectUnicode(true); //自动检测Unicode
textStream.setEncoding(getFileCharacterEncoding(fileName));
QString text = textStream.readAll(); //读取全部内容
file.close();
return text;
}
自定义类:
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QHeaderView>
#include <QInputDialog>
#include <QMessageBox>
#include <QObject>
#include <QPushButton>
#include <QString>
#include <QTableView>
#include <QTextCodec>
#include <QVector>
#include <QtSql>
enum EncodingFormat
{
ANSI,
UTF16LE,
UTF16BE,
UTF8,
UTF8BOM,
};
class Skysonya : public QObject
{
Q_OBJECT
Q_ENUM(EncodingFormat)
public:
explicit Skysonya(QObject *parent = nullptr);
~Skysonya();
QString doAppAbout(QString appName); //程序关于信息
bool messageBox(QString msgType, QString dlgTitle, QString strInfo); //中文提示对话框
QString inputDialog(QString dlgTitle, QString labelText, QString textValue = ""); //中文按钮文本输入对话框
QTextCodec *getFileCharacterTextCodec(const QString &fileName); //获取文件编码格式函数
QStringConverter::Encoding getFileCharacterEncoding(const QString &fileName); //获取文件编码格式函数
QString openFileByIOWhole(const QString &fileName); //用QFile打开文件,整体读取
QString openFileByIOLines(const QString &fileName); //用QFile打开文件,逐行读取
QString openFileByStreamWhole(const QString &fileName); //用QTextStream读取文件,整体读取
QString openFileByStreamLines(const QString &fileName); //用QTextStream读取文件,逐行读取
bool saveFileByIOWhole(const QString &fileName, QString text); //用QFile保存文件,整体保存
bool saveFileByStreamWhole(const QString &fileName, QString text); //用QTextStream保存文件,整体保存
void setTableViewBasicSettings(QTableView *tv); // TableView表基础设置
bool createTableBByTableAColumn(QSqlDatabase sqliteDB, QString tableB, QString tableA,
QString columnName); //根据数据表A某列创建数据表B
bool deleteTableRepeatRow(QSqlDatabase sqliteDB, QString tableName, QStringList ruleList); //删除数据表重复数据
bool createTableBByTableAColumn(QSqlDatabase sqliteDB, QString tableB, QString tableA,
QStringList columnList); //根据数据表A某列创建数据表B
bool readExcelToSQLiteByQXlsx(const QString &fileName, QSqlDatabase sqliteDB, QString tableName,
QString strTitle); //读取EXcel数据导入到SQLite数据库,使用QXlsx
bool writeTableviewToExcelByQXlsx(const QString &fileName, QString tableName, QTableView *tableView,
QString strTitle); //将QTableView数据写入EXcel,使用QXlsx
private:
QString appVersion; //软件版本号
QString buildTime; //程序构建时间
QString qtVersion; // QT版本号
QString fun_buildTime(); //获取程序构建时间
QString ArrayToString(int *array, int num)
{
QString output;
for (int i = 0; i < num; ++i)
{
if (i > 0)
{
output.append(", ");
}
output.append(QString::number(array[i]));
}
return output;
}; //数字数组转字符串
};
#endif // SKYSONYA_H