ModifyDatTime-98/mainwindow.cpp

363 lines
10 KiB
C++

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QDataStream>
#include <QByteArray>
#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
#include <QDate>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
folderPath = "";
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::ReadDat(QString fileName)
{
int year = ui->yearSpinBox->value();
int month = ui->monthSpinBox->value();
int day = ui->daySpinBox->value();
//转化为16进制
uint8_t hexYear = IntToHex(year);
uint8_t hexMonth = IntToHex(month);
uint8_t hexDay = IntToHex(day);
//QString filename = outputDir+"/"+fileName;
// // 一个示例日期年月日分别为2023年、12月、3日
// QDate date(year+2000, month, day);
// // 将日期格式化为yymmdd
// QString formattedDate = date.toString("yyyyMMdd");
// //修改文件名的时间信息
// QString f1 = fileName;
// f1.remove(11,f1.length()-11);
// QString f2 = fileName;
// f2.remove(0,11+8);
// QString str = f1+formattedDate+f2;
QString outputFileName = GetOutputFileName(fileName,year,month,day);
//创建修改后的dat文件
QFile writeFile(outputDir+"/"+outputFileName);
QDataStream outStream;
if (writeFile.open(QIODevice::WriteOnly)) {
// 创建数据流,用于写入二进制数据
// outStream = QDataStream(&writeFile);
outStream.setDevice(&writeFile);
outStream.setByteOrder(QDataStream::LittleEndian);
}
int len = 265;
quint8 *data = new quint8[len];
QFile file1 = QFile(folderPath+"/"+fileName);
//QFile file1 = QFile("E:\\dat\\output\\下行遥测_0_1_0_20230619230109.dat");
file1.open(QIODevice::ReadOnly);
QDataStream readStream = QDataStream(&file1);
readStream.setVersion(QDataStream::Qt_5_15); //设置数据流的版本
readStream.setByteOrder(QDataStream::LittleEndian);
int i =0;
quint8* content = new quint8[28]; //创建一个28字节的数据缓冲区
// int sub1 = 0;
// int sub2 = 0;
while(!readStream.atEnd())
{
readStream.readRawData((char *)data, len); //读取一帧
// i++;
//四个子帧解析
// int id1 = 16;
// int id2 = id1+32;
// int id3 = id2+32;
// int id4 = id3+32;
int startID = 16;
for (int var = 0; var < 4; ++var) {
startID = 16 + 32*var;
// if(data[startID]!=0x23)
// qDebug()<<"************Zhen1:"<<data[startID];
// if(data[startID+1]!=0x23)
// qDebug()<<"************Zhen2:"<<data[startID];
quint8 zhenID = data[startID+4];
if(zhenID==0x87 || zhenID==0x89 || zhenID==0x8A)
{
// if(data[startID+17]==0x01)
// {
// //quint32 ss = quint32(data[startID+25] | (data[startID+26]<<8) | (data[startID+27]<<16) | (data[startID+28]<<24))*0.001;
// //qDebug()<<"************SS:"<<ss;
// quint8 vid = quint8(data[startID+29]);
// //qDebug()<<"************vid1:"<<vid;
// }
if(data[startID+17]==0x02) //子帧2
{
// quint8 d = quint8(data[startID+18]);
// quint8 m = quint8(data[startID+19]);
//quint8 y = quint8(data[startID+20]);
//qDebug()<<"************Year:"<<y;
// int a = 1;
//修改UTC年月日数据
if(hexDay>0)
data[startID+18] = hexDay;
if(hexMonth>0)
data[startID+19] = hexMonth;
if(hexYear>0)
data[startID+20] = hexYear;
//计算CRC16校验位
for(int i=0;i<28;i++)//提取数据帧内容
{
content[i] = data[startID+2+i];
}
quint16 crc = GetCrcSum(content,28);//计算校验码
// 提取高位和低位
quint8 highByte = static_cast<quint8>((crc >> 8) & 0xFF);
quint8 lowByte = static_cast<quint8>(crc & 0xFF);
//修改CRC校验位
data[startID+30] = lowByte;
data[startID+31] = highByte;
}
}
}
// bool b = data[16]==0x23;
// bool b1 = data[17]==0x23;
// bool b2 = data[18]==0x85;
//修改系统时间戳
if(hexYear>0)
data[2] = hexYear;
if(hexMonth>0)
data[3] = hexMonth;
if(hexDay>0)
data[4] = hexDay;
//修改最后校验位
data[len-1] = GetDataCheckCRC(data,len);
//写入文件
outStream.writeRawData((char *)data,len);
}
file1.close();
writeFile.close();
qDebug()<<"*********************i:"<<i;
}
uint8_t MainWindow::IntToHex(int data)
{
// 将十进制整数转换为十六进制表示
QByteArray hexData = QByteArray::number(data, 16);
// 将十六进制表示转换为 uint8_t 类型
bool ok;
return hexData.toUInt(&ok, 16);
}
/*******************************************************************************
GetCrcSum
CRC
CRC
*******************************************************************************/
quint16 MainWindow::GetCrcSum(quint8 *dataptr, quint16 len)
{
qint16 count = 0;
quint8 C0 = 0,C1 = 0,Y0 = 0,Y1 = 0,Z0 = 0,Z1 = 0;
C0=C1=Y0=Y1=Z0=Z1=0;
while(count < len)
{
Y0=(CRCLIST[2*(*dataptr)]^C1) & 0x00FF;
Y1=(CRCLIST[2*(*dataptr)+1]) & 0x00FF;
Z0=CRCLIST[2*C0] & 0x00FF;
Z1=CRCLIST[2*C0+1] & 0x00FF;
C0=(Y0^Z0) & 0x00FF;
C1=(Y1^Z1) & 0x00FF;
dataptr++;
count++;
}
return(C0+C1*256);/* return crc result */
}
quint8 MainWindow::GetDataCheckCRC(quint8 *dataptr, quint16 len)
{
quint8 sum = 0;
for(int i = 0;i<264;i++)
{
sum += quint8(dataptr[i]);
}
return quint8(~(sum & 0xFF)+1);
}
/**
*
*
* @param year
* @return truefalse
*/
bool MainWindow::isLeapYear(int year)
{
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
return true;
} else {
return false;
}
}
/**
*
*
* @param year
* @param month
* @param day
* @return truefalse
*/
bool MainWindow::isValidDay(int year, int month, int day)
{
if (month == 2) {
if (isLeapYear(year)) {
if (day >= 1 && day <= 29) {
return true;
}
} else {
if (day >= 1 && day <= 28) {
return true;
}
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
if (day >= 1 && day <= 30) {
return true;
}
} else {
if (day >= 1 && day <= 31) {
return true;
}
}
return false;
}
QString MainWindow::GetOutputFileName(QString fileName,int year, int month, int day)
{
//QString str = "下行遥测_0_17_0_20221114024453.dat";
QStringList strList = fileName.split("_");
QString endstr = strList.constLast();
QString lastStr = endstr.mid(8,-1);
if(year==0)
year = endstr.mid(0,4).toInt()-2000;
//QString year0 = endstr.mid(0,4);
if(month==0)
month = endstr.mid(4,2).toInt();
if(day==0)
day = endstr.mid(6,2).toInt();
// QString month = endstr.mid(4,2);
// QString day = endstr.mid(6,2);
// 一个示例日期年月日分别为2023年、12月、3日
QDate date(year+2000, month, day);
// 将日期格式化为yymmdd
QString formattedDate = date.toString("yyyyMMdd");
QString outputFileName = "";
strList.removeLast();
strList.append(formattedDate);
outputFileName = strList.join("_") + lastStr;
// for (int var = 0; var < strList.length()-2; ++var) {
// outputFileName += strList.at(var);
// }
return outputFileName;
}
void MainWindow::on_openDirBtn_clicked()
{
// 创建一个QFileDialog对象
QFileDialog dialog;
// 设置对话框的标题
dialog.setWindowTitle("Select Folder");
// 设置对话框模式为选择文件夹
dialog.setFileMode(QFileDialog::Directory);
// 打开对话框
if (dialog.exec()) {
// 获取用户选择的文件夹路径
folderPath = dialog.selectedFiles().at(0);
qDebug() << "Selected Folder: " << folderPath;
} else {
qDebug() << "User canceled the operation.";
}
}
void MainWindow::CreateDir()
{
// 创建一个QDir对象
QDir dir;
outputDir = folderPath+"/output";
// 设置目录路径
dir.setPath(outputDir);
// 创建文件夹
if (dir.mkpath(outputDir)) {
qDebug() << "Folder created successfully.";
} else {
qDebug() << "Failed to create folder.";
}
//QDir directory(folderPath+"/output");
}
void MainWindow::on_startModifyBtn_clicked()
{
int year = ui->yearSpinBox->value();
int month = ui->monthSpinBox->value();
int day = ui->daySpinBox->value();
if(year<=0&&month<=0&&day<=0)
{
QMessageBox::information(NULL,"提示","请设置要修改的年月日!!!");
return;
}
if(folderPath=="")
{
QMessageBox::information(NULL,"提示","请先设置文件夹!!!");
return;
}
// 检查Day是否正确
if(day>0 && !isValidDay(year+2000,month,day))
{
QMessageBox::information(NULL,"提示","日期有误,请重新设置!!!");
return;
}
// 创建一个 QDir 对象
QDir directory(folderPath);
// 获取文件夹中的所有文件
QStringList files = directory.entryList(QDir::Files);
int numFiles = files.length();
if(numFiles==0)
{
QMessageBox::information(NULL,"提示","该文件夹没有dat文件!!!");
return;
}
//新建output文件夹
CreateDir();
//开始处理
for (int n = 0; n < numFiles; ++n)
{
ReadDat(files.at(n));
}
QMessageBox::information(NULL,"提示","处理结束!!!");
}