平台公司审计重点/seo每日一贴

平台公司审计重点,seo每日一贴,wordpress ajax登录页面,南昌网站建设公司渠道前言 最近在做项目时遇到一个需求,需要将升级的文件压缩成zip,再进行传输; 通过网络调研,有许多方式可以实现,例如QT私有模块的ZipReader、QZipWriter;或者第三方库zlib或者libzip或者quazip等&#xff1…

前言

最近在做项目时遇到一个需求,需要将升级的文件压缩成zip,再进行传输;

通过网络调研,有许多方式可以实现,例如QT私有模块的ZipReader、QZipWriter;或者第三方库zlib或者libzip或者quazip等;其中libzip和quazip都是依赖于zlib;

然后,这些都需要变成库,然后再链接到QT项目中进行使用;

由于项目的特殊性,有可能需要在window,Linux和ARM三个平台上去运行,如果都编译为库去使用的话,那么需要编译三个平台,甚是麻烦,而且如果系统版本不一样,可能还不能用;

所以,现阶段有两种方案,其一是使用QT自带的压缩库,其二是使用第三方库的源码;

由此可知,使用QT自带的私有库是最方便,且网络上也有教程(文章最后也提供的操作代码);

但是,使用QT自带的私有库有几个缺点,第一是需要QT5.14以上的版本才可以使用,且在QT6中已经移除了该模块;而且需要安装QT时勾选安装QT源码才可以使用;由此,这种方式pass掉;

本人在ARM平台安装QT,是使用命令行在线安装的,QT的版本无法控制,也无法安装源码!

只能使用第二种方式了,遂在网络上寻找第三方库的源码,如何将将源码潜入到QT项目中去;

网络上教程,百分之99.99都是叫你如何编译使用的,剩下百分之0.01是需要vip和付费资源,完全没有使用源码的方式;

直到我遇到了一篇博客,里面博主就是使用Quazip+Zlib源码,用于异步压缩文件为zip格式,且博主将代码开源,正好符合我的需求,再次非常感谢该博主,链接如下:

Qt+Quazip+Zlib源码工程实现带进度同步异步加解压文件_qt 压缩zip 进度-CSDN博客

但是,该项目源码也使用到了QT的私有模块,对于我这种在ARM平台下使用命令行安装的QT,且版本没有达到5.14的我来说,无疑是晴天霹雳;

项目无法运行,报错!!!

没办法,只能自己手动去修改,这难不倒身为程序员的我!

我将代码中的私有模块去掉,将博主写的压缩解压缩代码也去掉,自己动手写了一个操作类,使用了Quazip的接口,供外部使用!(同步 压缩/解压缩)

完成后,突然想起来,还有加密压缩的需求,这该怎么办呢?

在网络上调研了一整天,没啥博客能讲明白或者能使用quazip库直接给出代码的;

直到我遇到了另一篇博客,里面有分享了一些 加密压缩多个文件 和 解压含密码的压缩文件 的案例;

通过参考这些案例,我写出来自己的加密压缩和解密压缩文件和文件夹的操作函数,经过测试可行;

再次也非常感谢该博主的分享,博文链接如下:

Qt加密压缩与解压-CSDN博客

到了这一步,项目需求的加密压缩和解密压缩基本就完成了;

但转念一想,平常事我们使用的解压缩软件时,都是带有进度条的,也就是说下解压缩时,我们应该需要知道进度;

于是乎,再次修改代码,增加了解压缩操作时,将当前进度通过信号发射出去,由调用方处理这个信号即可!

因为我实现的解压缩功能是同步的,所以,调用方在处理解压缩时,如果不希望卡屏,就得使用线程去操作;

由此写出了一个简易的解压缩zip软件,运行效果如下:

压缩成功后

解压缩和压缩文件是一样的,这里就不放出演示了!

对比一下压缩后的大小:

效果还是很明显的!


目录

前言

一、基础的解压缩

二、自定义实现解压缩

1.加密压缩

1).打开zip文件

2).获取需要压缩的文件夹内部的所有文件及子文件

3).创建一个QuaZipFile 

4).遍历获取到的所有文件列表

5).创建新的ZIP文件条目信息

6).打开ZIP文件条目

7).读取写入

8).关闭文件

9).详细代码

2.解密解压缩

1).创建文件夹

 2).打开zip文件

3).获取zip内的所有文件条目

4).遍历这个链表

5).处理文件夹

 6).创建一个QuaZipFile 

7).打开QuaZipFile

8).读取写入(解压缩)

 9).关闭文件

10).详细代码

三、源码分享

1.下载后如何引入自己的项目工程中?

1).拷贝quazip文件夹到自己的项目工程中

2).在自己的项目的.pro文件引入如下代码

3).包含头文件

2.QT自带压缩库操作分享 ZipReader、QZipWriter

1).导入私有模块

2).zipcompress.h

3).zipcompress.cpp

四、结束语


一、基础的解压缩

网络上介绍Quazip库使用的,基本都是以下这些:

JlCompress mJlCompress;// 压缩文件
mJlCompress.compressFiles(fileCompressed,files);// 解压文件夹
mJlCompress.extractDir(fileCompressed, dir);// 压缩文件夹
mJlCompress.compressDir(fileCompressed, dir, recursive);// 解压文件
mJlCompress.extractFiles(fileCompressed, files);

其实如果是基础用法,上面这几句代码也够用了;

但是如果涉及到加密压缩和进度方面,就得自己去实现解压缩的过程了,且这样也更加灵活一点!

二、自定义实现解压缩

Quazip库还提供了QuaZipQuaZipFileQuaZipNewInfoQuaZipFileInfo

等类供我们自己去处理!

QuaZip 类用于打开一个.zip文件;

QuaZipFile 类用于处理zip内部的文件,即读取zip内部文件数据(解压)或者往zip内部写入文件(压缩);【在此可以进行加密和解密处理】

QuaZipNewInfo 类用于定义一个zip的文件信息,在压缩时使用;

QuaZipFileInfo 类用于处理一个zip内部的文件;

当然,还有以下这么多:(别家复制过来的)

说明
JlCompress典型操作工具类
QuaAdler32Adler32算法校验和
QuaChecksum32校验和接口
QuaCrc32CRC32校验和
QuaGzipFileGZIP 文件操作
QuaZIODevice压缩/解压 QIODevice
QuaZipZIP 文件
QuaZipDirZIP文件内目录导航
QuaZipFileZIP文件内的文件
QuaZipFileInfoZIP压缩包内的文件信息
QuaZipFilePrivateQuaZip的接口
QuaZipNewInfo被创建的文件信息
QuaZipPrivateQuaZIP内部类

下面是加密压缩和解密压缩的过程分析;

1.加密压缩

这里处理的是压缩文件夹,压缩文件与之类似;

压缩后的文件结构与原来一致;

1).打开zip文件

QuaZip newZip(fileCompressed); // 要生成的zip文件                         
if (!newZip.open(QuaZip::mdCreate)) {                               qDebug() << "Failed to create ZIP file:" << fileCompressed;                                 return false;                                                  
}

参数枚举介绍:

enum Mode {mdNotOpen,        ///< ZIP文件未打开。这是初始模式。mdUnzip,          ///< ZIP文件已打开,用于读取其内部的文件。mdCreate,         ///< ZIP文件已通过open()调用创建。mdAppend,         ///< ZIP文件以追加模式打开。这指的是ZIP/UNZIP包中的APPEND_STATUS_CREATEAFTER模式,///  意味着zip被追加到某个已存在的文件中,该文件包含自解压代码。这显然不是您想要用来///  向现有的ZIP归档添加文件的模式。mdAdd             ///< ZIP文件已打开,用于向归档中添加文件。
};

一般来说,我们只需要用到 mdUnzip 用于解压缩 和 mdCreate 用于压缩即可!

2).获取需要压缩的文件夹内部的所有文件及子文件

QStringList filePathList = 获取所有文件();

3).创建一个QuaZipFile 

QuaZipFile zipFile(&newZip);

使用QuaZip作为参数;

4).遍历获取到的所有文件列表

在循环体内部处理压缩事项;以下操作都是在循环体内部进行;

5).创建新的ZIP文件条目信息

QuaZipNewInfo info(文件名, 文件路径+文件名);

6).打开ZIP文件条目

if (!zipFile.open(QIODevice::WriteOnly, info, password.toUtf8().constData(), 0, 8)) {  qDebug() << "Failed to open ZIP entry for writing:" << fileName;                            // 关闭ZIP                                                                                    newZip.close();                                                                                                                                return false;                                                                              
}

open参数介绍:

bool open(OpenMode mode,               // 打开模式,指定是以什么方式打开文件(例如,只写、追加等)const QuaZipNewInfo& info,   // 文件信息,包括文件名、时间戳等const char *password = nullptr, // 密码,用于加密文件,如果不需要加密则传递nullptrquint32 crc = 0,             // CRC校验码,通常设置为0,除非在原始模式下使用int method = Z_DEFLATED,     // 压缩方法,Z_DEFLATED表示使用Deflate算法,Z_BZIP2ED表示使用BZIP2算法,0表示不压缩int level = Z_DEFAULT_COMPRESSION, // 压缩级别,对于Deflate算法,可以是0-9之间的值,Z_DEFAULT_COMPRESSION表示默认级别// 以下保持默认即可!!!bool raw = false,            int windowBits = -MAX_WBITS, int memLevel = DEF_MEM_LEVEL,int strategy = Z_DEFAULT_STRATEGY 
);

需要注意的是,

src参数,通常设置为0,除非你知道使用其他值,所带来的后果;

method参数,需要设置为8,即宏Z_DEFLATED,这个是压缩算法,注意,quazip只支持这种算法,所以必须设置为8;

level参数,是压缩等级,可设置0-9,之间的任何一个数字,0表示无压缩,最快,9表示最大压缩,但最慢,一般设置为默认值即可!

其实也就是说,只需要设置前面三个参数即可!!!

7).读取写入

使用QFile读取本地文件数据,写入QuaZipFile中

QFile sourceFile(filePath);
sourceFile.open(QIODevice::ReadOnly);
zipFile.write(sourceFile.readAll());    // 注意,处理大文件时,这里会崩溃

注意,上面写法在处理大文件时会有问题,readAll()函数会将文件数据读如内存中,如果文件太大,会将堆内存给撑爆,程序就闪退了;

所以为了避免这样的问题,在处理大文件时,必须分块进行处理!

QByteArray buffer;                                    
while(!sourceFile.atEnd()) {                          buffer = sourceFile.read(4096);    // 每次读取一页内存数据          zipFile.write(buffer);                            
}

8).关闭文件

最后记得在循环尾部将文件关闭后,再进行新一轮的文件读写操作!

sourceFile.close();
zipFile.close();

处理完毕后,记得关闭 newZip.close();

加密压缩文件部分与之类似,这里就不展开讲解了!

给出函数接口,自己动手去实现一下吧;

    /*** @brief 加密压缩多个文件* @param fileCompressed        压缩包名* @param files                 要解压的文件列表* @param password              密码* @return*/bool compressFilesWithPassword(const QString &fileCompressed,const QStringList &files,const QString& password);

9).详细代码

进度部分就不详细讲解了,都在代码函数中

/**                               * @brief 加密压缩文件夹内的所有文件           * @param fileCompressed    压缩包名-路径  * @param dir               压缩路径  * @param password          密码    * @return                        */                               
bool zipCompress::compressDirsWithPassword(const QString &fileCompressed, const QString &dir, const QString &password) {bool result = false;if (fileCompressed.isEmpty() || dir.isEmpty()) {emit signalCompressDirinish(result);return result;}QuaZip newZip(fileCompressed); // 要生成的zip文件if (!newZip.open(QuaZip::mdCreate)) {qDebug() << "Failed to create ZIP file:" << fileCompressed;emit signalCompressDirinish(result);return result;}// 读取目录中的所有文件QStringList filePathList = listFilesInDirectoryRecursively(dir);if (filePathList.isEmpty()) {qDebug() << "No files to compress in directory:" << dir;newZip.close();emit signalCompressDirinish(result);return result;}qreal pro = 100.0 / filePathList.size();qreal progress = 1.0;QuaZipFile zipFile(&newZip);for (const QString &filePath : filePathList) {// 构造相对于dir的文件名QString fileName = QDir(dir).relativeFilePath(filePath);// 创建ZIP文件条目信息QuaZipNewInfo info(fileName, filePath);// 尝试打开ZIP文件条目进行写入if (!zipFile.open(QIODevice::WriteOnly, info, password.toUtf8().constData(), 0, 8)) {qDebug() << "Failed to open ZIP entry for writing:" << fileName;// 关闭ZIPnewZip.close();emit signalCompressDirinish(result);return result;}// 打开源文件进行读取QFile sourceFile(filePath);if (!sourceFile.open(QIODevice::ReadOnly)) {qDebug() << "Failed to open source file for reading:" << filePath;// 关闭ZIPnewZip.close();emit signalCompressDirinish(result);return result;}// 总进度emit signalCompressionProgress(progress, "1", filePath);// 大文件读取分块处理,否则程序会闪退{qreal file_pro = 100.0 / (sourceFile.size() / mBlockSize);qreal file_progress = 0.0;// 将源文件的内容写入ZIP文件QByteArray buffer;while(!sourceFile.atEnd()) {buffer = sourceFile.read(mBlockSize);zipFile.write(buffer);file_progress += file_pro;emit signalFileProgress(file_progress, filePath);}emit signalFileProgress(100, filePath);}sourceFile.close();zipFile.close();progress += pro;progress = qBound(0.0, progress, 99.999);}result = true;newZip.close();emit signalCompressionProgress(100, "1", "");emit signalCompressDirinish(result);return result;
}QStringList zipCompress::listFilesInDirectoryRecursively(const QString &directoryPath) {QStringList list;QDirIterator it(directoryPath, QDir::Files, QDirIterator::Subdirectories);while (it.hasNext()) {QString filePath = it.next();list.append(filePath);}return list;
}

2.解密解压缩

这里处理的是解压缩一个zip文件;

解压出来文件结构与压缩包内一致!

1).创建文件夹

判断传进来的路径解压路径,如果不存在则创建

 2).打开zip文件

QuaZip zip(fileCompressed);                                       
if (!zip.open(QuaZip::mdUnzip)) {                                 qDebug() << "Failed to open ZIP file:" << fileCompressed;                          return false;                                                
}

因为是解压缩,所以参数使用mdUnzip

3).获取zip内的所有文件条目

QList<QuaZipFileInfo> fileInfoList = zip.getFileInfoList();

4).遍历这个链表

解压缩操作都在这个循环体内进行;

5).处理文件夹

如果处理的当前文件,在本机电脑中还没有路径,则进行创建;

且跳过是文件夹的操作!

 6).创建一个QuaZipFile 

QuaZipFile zipFile(zip.getZipName(), 文件名);

7).打开QuaZipFile

zipFile.open(QIODevice::ReadOnly, password.toUtf8().constData());

参数二是密码;

8).读取写入(解压缩)

注意,为了防止大文件的问题,读取写入是还是分块进行操作! 

QByteArray buffer;                                        
while(!zipFile.atEnd()) {                                 buffer = zipFile.read(4096);                    outFile.write(buffer);                                  
}

 9).关闭文件

最后记得在循环尾部将文件关闭后,再进行新一轮的文件读写操作!

outFile.close();    
zipFile.close();    
处理完毕后,记得关闭 zip.close();

10).详细代码

进度部分就不详细讲解了,都在代码函数中

bool zipCompress::extractDirWithPassword(const QString &fileCompressed, const QString &dir, const QString &password) {bool result = false;if (fileCompressed.isEmpty() || dir.isEmpty()) {emit signalExtractDirFinish(result);return result;}// 使用QFileInfo获取文件名(不带扩展名)并构建目标目录路径QFileInfo fileInfo(fileCompressed);QString targetDirName = fileInfo.completeBaseName();QString targetDirPath = QDir(dir).absoluteFilePath(targetDirName);// 创建目标目录(如果不存在)QDir targetDir(targetDirPath);if (!targetDir.exists() && !targetDir.mkpath(".")) {qDebug() << "Failed to create target directory:" << targetDirPath;emit signalExtractDirFinish(result);return result;}// 打开ZIP文件QuaZip zip(fileCompressed);if (!zip.open(QuaZip::mdUnzip)) {qDebug() << "Failed to open ZIP file:" << fileCompressed;emit signalExtractDirFinish(result);return result;}// 遍历ZIP文件中的所有条目QList<QuaZipFileInfo> fileInfoList = zip.getFileInfoList();qreal pro = 100.0 / fileInfoList.size();qreal progress = 1.0;for (const QuaZipFileInfo &fileInfoEntry : fileInfoList) {// 组合目标文件路径QString fileName = fileInfoEntry.name;QString filePath = targetDir.absoluteFilePath(fileName);// 如果是文件夹,如果不存在则创建;然后跳过文件夹的操作QFileInfo info(filePath);if (info.isDir()) {QDir().mkpath(filePath);continue;} else {    // 如果是文件,如果路径不存在,创建该路径QString path = info.path();QDir dpath(path);if (!dpath.exists()) {if (!dpath.mkpath(path)) {qDebug() << "Failed to create directory:" << path;emit signalExtractDirFinish(result);return result;}}}// 打开ZIP条目并解压文件QuaZipFile zipFile(zip.getZipName(), fileName);if (zipFile.open(QIODevice::ReadOnly, password.toUtf8().constData())) {QFile outFile(filePath);if (!outFile.open(QIODevice::WriteOnly)) {qDebug() << "Failed to open output file for writing:" << filePath;zipFile.close();zip.close();emit signalExtractDirFinish(result);return result;}emit signalCompressionProgress(progress, "2", filePath);// 大文件读取分块处理,否则程序会闪退{qreal file_pro = 100.0 / (zipFile.size() / mBlockSize);qreal file_progress = 0.0;// 解压并写入文件QByteArray buffer;while(!zipFile.atEnd()) {buffer = zipFile.read(mBlockSize);outFile.write(buffer);file_progress += file_pro;emit signalFileProgress(file_progress, filePath);}emit signalFileProgress(100, filePath);}outFile.close();zipFile.close();} else {qDebug() << "Failed to open ZIP entry for reading:" << fileName;zip.close();emit signalExtractDirFinish(result);return result;}progress += pro;progress = qBound(0.0, progress, 99.999);}result = true;// 关闭ZIP文件zip.close();emit signalCompressionProgress(100, "2", "");emit signalExtractDirFinish(result);return result;
}

三、源码分享

到此,解压缩已经介绍完毕,现在分享我参考写的解压缩程序

https://download.csdn.net/download/cpp_learner/90411497https://download.csdn.net/download/cpp_learner/90411497因为我这边编写的压缩和解压缩操作都是同步的,所以,建议操作时使用线程去处理,否则会卡屏,而且进度条也无法使用;

在我给出的案例工程中,就是使用了线程去解压缩等操作,有兴趣可以学习一下!

1.下载后如何引入自己的项目工程中?

1).拷贝quazip文件夹到自己的项目工程中

2).在自己的项目的.pro文件引入如下代码

# 源码方式使用需要设置为静态库
DEFINES +=   QUAZIP_STATIC
include($$PWD/quazip/3rdparty/zlib.pri)
include($$PWD/quazip/quazip.pri)
include($$PWD/quazip/zipop/zipop.pri)

3).包含头文件

#include "zipcompress.h"

头文件包含后,就可以直接使用了 

compressionTool::zipCompress m_zipCompress;                                  
// 压缩文件夹                                                                     
m_zipCompress.compressDirsWithPassword(mZipPath, mPath, mPassword);        // 解压缩                                                                       
m_zipCompress.extractDirWithPassword(fileName, fileinfo.path(), "abc@123");  // 压缩文件                                                                    
m_zipCompress.compressFilesWithPassword(mZipPath, mFiles, mPassword);      

2.QT自带压缩库操作分享 ZipReader、QZipWriter

以下是我编写好的操作类,直接新建文件拷贝代码到文件中即可使用!

(注意,一般来说,需要QT5.14以上的版本才可以使用)

1).导入私有模块

.pro文件中添加私有模块

QT       += gui-private

2).zipcompress.h

#ifndef ZIPCOMPRESS_H
#define ZIPCOMPRESS_H#include <QObject>
#include <QtGui/private/qzipreader_p.h>
#include <QtGui/private/qzipwriter_p.h>class ZipCompress : public QObject
{Q_OBJECT
public:ZipCompress(QObject *parent = nullptr);/*** @brief 压缩文件* @param fileNames 需要压缩的文件名* @param saveName  压缩后的文件路径和名字*/bool zipCompressFile(const QStringList &fileNames, const QString &saveName);/*** @brief 压缩文件夹* @param dirName   需要压缩的文件夹名* @param saveName  压缩后的文件路径和名字*/bool zipCompressDirector(const QString &dirName, const QString &saveName);/*** @brief 解压缩* @param zipFile   压缩包* @param saveDir   解压路径* @return*/bool zipUnCompressFile(const QString &zipFile, const QString &saveDir);private:/*** @brief 递归压缩* @param zipWriterHandle       QZipWriter指针* @param zipParentDirName      父路径,相对路径* @param srcDir                当前需要处理的文件夹路径,绝对路径*/void zipCompressDirector(void *zipWriterHandle, const QString &zipParentDirName, const QString &srcDir);private:QZipReader *mZipReader;QZipWriter *mZipWriter;
};#endif // ZIPCOMPRESS_H

3).zipcompress.cpp

#include "zipcompress.h"#include <QFileInfo>
#include <QDir>
#include <QDebug>ZipCompress::ZipCompress(QObject *parent): QObject(parent)
{
}bool ZipCompress::zipCompressFile(const QStringList &fileNames, const QString &saveName)
{QZipWriter *zipWriter = new QZipWriter(saveName);if (!zipWriter) {qDebug() << "压缩失败!";return false;}QFile file;QFileInfo fileInfo;foreach (const QString &fileName, fileNames) {if (fileName.isEmpty() || "" == fileName) {continue;}// 判断文件是否存在fileInfo.setFile(fileName);if (!fileInfo.exists()) {qDebug() << fileName << " : 文件不存在!";continue;}if (fileInfo.isFile()) {// 打开文件file.setFileName(fileName);if (!file.open(QIODevice::ReadOnly)) {qDebug() << fileName << " : 文件打开失败!";continue;}// 添加到压缩包中zipWriter->addFile(fileInfo.fileName(), file.readAll());file.close();} else if (fileInfo.isDir()) {// 添加到压缩包中zipWriter->addDirectory(fileName);}}zipWriter->close();if (zipWriter) {delete zipWriter;zipWriter = nullptr;}return true;
}bool ZipCompress::zipCompressDirector(const QString &dirName, const QString &saveName)
{QFile file(saveName);if (!file.open(QFile::WriteOnly)) {qDebug() << "压缩失败!";return false;}std::shared_ptr<QZipWriter> zipWriter(new QZipWriter(&file));if (!zipWriter) {qDebug() << "压缩失败!";return false;}zipCompressDirector(zipWriter.get(), "", dirName);zipWriter->close();file.close();return true;
}bool ZipCompress::zipUnCompressFile(const QString &zipFile, const QString &saveDir)
{QFile file(zipFile);if (!file.open(QIODevice::ReadOnly)) {qDebug() << zipFile << " : 文件打开失败!";return false;}QDir dir(saveDir);if (!dir.exists()) {if (!dir.mkpath(saveDir)) { // 创建文件夹qDebug() << saveDir << " : 文件夹路径不存在,且创建失败!";return false;}}std::shared_ptr<QZipReader> zipReader(new QZipReader(&file));return zipReader->extractAll(saveDir);  // 全部解压出来
}void ZipCompress::zipCompressDirector(void *zipWriterHandle, const QString &zipParentDirName, const QString &srcDir)
{QZipWriter *zipWriter = (QZipWriter *)zipWriterHandle;QDir directory(srcDir);QFileInfoList fileList = directory.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);for (const QFileInfo &fileInfo : fileList) {QString relatePath = fileInfo.fileName();       // 获取当前文件名 | 文件夹名if (!zipParentDirName.isEmpty()) {relatePath.prepend(zipParentDirName + "/"); // 头部拼接上父路径,相对路径}QString filePath = fileInfo.absoluteFilePath(); // 获取当前文件的绝对路径if (fileInfo.isDir()) {// 添加文件夹zipWriter->addDirectory(relatePath);// 参数二:文件夹相对路径      参数三:文件夹绝对路径zipCompressDirector(zipWriter, relatePath, filePath);} else {QFile file(filePath);if (!file.open(QIODevice::ReadOnly)) {qDebug() << filePath << " : 文件打开失败!";continue;}zipWriter->addFile(relatePath, file.readAll());file.close();}}
}

四、结束语

文章最后,感谢各位能够坚持看完,相信此篇文章也会对你有所帮助;

当然,我上面所给出的只是一些基础用法,还有很多高级用法我也还没整明白;

或者哪位大佬有更好的实现方式,也欢迎评论区分享出来,供大家一起探讨学习;

完!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/896417.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Fiddler在Windows下抓包Https

文章目录 1.Fiddler Classic 配置2.配置浏览器代理自动代理手动配置浏览器代理 3.抓取移动端 HTTPS 流量&#xff08;可选&#xff09;解决抓取 HTTPS 失败问题1.Fiddler证书过期了 默认情况下&#xff0c;Fiddler 无法直接解密 HTTPS 流量。需要开启 HTTPS 解密&#xff1a; 1…

DINOv2 + yolov8 + opencv 检测卡车的可拉拽雨覆是否完全覆盖

最近是接了一个需求咨询图像处理类的&#xff0c;甲方要在卡车过磅的地方装一个摄像头用检测卡车的车斗雨覆是否完全&#xff0c; 让我大致理了下需求并对技术核心做下预研究 开发一套图像处理软件&#xff0c;能够实时监控经过的卡车并判断其车斗的雨覆状态。 系统需具备以下…

AI除了可以能提高工作效率的还可以实现哪些功能?

AI除了能显著提高工作效率之外&#xff0c;其在众多领域的潜力远不止于此。 在教育领域&#xff0c;AI正逐步成为个性化教学的得力助手。通过分析学生的学习习惯和能力水平&#xff0c;AI能够定制出最适合每个学生的学习计划&#xff0c;不仅提升了学习效率&#xff0c;还极大地…

vscode settings(一):全局| 用户设置常用的设置项

参考资料 Visual Studio Code权威指南 by 韩骏 一. 全局设置与用户设置 1.1 Vscode支持两种不同范围的设置 用户设置(User Settings)&#xff1a;这是一个全局范围的设置&#xff0c;会应用到所有的Visual Studio Code实例中。工作区设置(Workspace Settings)&#xff1a;设…

seacmsv9注入管理员账号密码+orderby+limit

一、seacmsv9 SQL注入漏洞 1.1 seacms漏洞介绍 海洋影视管理系统&#xff08;seacms&#xff0c;海洋cms&#xff09;是一套专为不同需求的站长而设计的视频点播系统&#xff0c;采 用的是 php5.Xmysql 的架构&#xff0c;seacmsv9漏洞文件&#xff1a;./comment/api/index.p…

WPF学习之Prism(二)

前言 学习一下Prism。 1.Prism Prism框架提供了一套丰富的工具、类和模块&#xff0c;帮助开发人员实现以下功能&#xff1a; 模块化&#xff1a;Prism框架支持将应用程序拆分为多个模块&#xff0c;每个模块具有自己的功能和视图。这种模块化的设计使得应用程序更加灵活和…

【EB-03】 AUTOSAR builder与EB RTE集成

AUTOSAR builder与EB RTE集成 1. Import Arxml files to Tresos2. Run MultiTask Script3. Add Components3.1 Run EcuExtractCreator Script4. Mapping Component to Partitions5. Event Mapping/Runnables Mapping to Tasks6. Port Connect7. Run SvcAs_Trigger Script8. Ver…

算法教程:香槟塔问题

香槟塔问题 问题描述 我们将玻璃杯堆成金字塔状,第一排有 1 个玻璃杯,第二排有 2 个玻璃杯,依此类推,直到第 100 排。每个玻璃杯装一杯香槟。 然后,将一些香槟倒入最上面的第一个玻璃杯中。当最上面的玻璃杯装满时,任何多余的液体都会均匀地落到它左右两侧的玻璃杯上。当…

FastJSON 默认行为:JSON.toJSONString 忽略 null 字段

完整的 FakeRegistrationController 代码&#xff0c;这让我可以全面分析后端逻辑&#xff0c;特别是为什么空的字段&#xff08;如 compareDate&#xff09;不返回给前端。我将详细分析代码的每个接口&#xff0c;尤其是与 list 请求和字段返回相关的部分&#xff0c;并解释原…

在Linux环境下利用MTCNN进行人脸检测(基于ncnn架构)

概述 本文将详细介绍如何在Linux环境下部署MTCNN模型进行人脸检测&#xff0c;并使用NCNN框架进行推理。 1. CMake的安装与配置 下载CMake源码 前往CMake官网下载&#xff0c;找到适合您系统的最新版本tar.gz文件链接&#xff0c;或者直接通过wget下载&#xff1a;CMake官方…

算法day1 dfs搜索2题

一 火星人 拿到这种类似于排序的&#xff0c;这个就好比如我们之前学习dfs基础的时候里面的指数型枚举 指数型枚举数据与数据之间没有任何枚举&#xff0c;就比如选这个数字与不选组合型枚举数据与数据之间有联系&#xff0c;下一个数字不可以给上一个数字排列型枚举数据与数…

【MySQL篇】数据库基础

目录 1&#xff0c;什么是数据库&#xff1f; 2&#xff0c;主流数据库 3&#xff0c;MySQL介绍 1&#xff0c;MySQL架构 2&#xff0c;SQL分类 3&#xff0c;MySQL存储引擎 1&#xff0c;什么是数据库&#xff1f; 数据库&#xff08;Database&#xff0c;简称DB&#xf…

网络安全事件研判

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 研判&#xff08;入侵检测&#xff09; 研判我理解为人工层面对入侵检测事件进行再分析&#xff0c;即借助已有的设备告警根据经验判断是否为真实action 研判工作…

python整理文件下

我们使用 os.path.join() 函数拼接出文件要移动的目标地址。 并使用 os.path.exists() 函数配合 not 关键字找到未创建的文件夹。 这节课&#xff0c;我们会先创建文件夹&#xff0c;然后再移动文件到目标文件夹。如果文件夹不存在&#xff0c;我们需要先创建文件夹&#xff…

hackmyvm-buster

题目地址 信息收集 主机发现 ┌──(root㉿kali)-[/home/kali] └─# arp-scan -I eth1 192.168.56.0/24 Interface: eth1, type: EN10MB, MAC: 00:0c:29:34:da:f5, IPv4: 192.168.56.103 WARNING: Cannot open MAC/Vendor file ieee-oui.txt: Permission denied WARNING: C…

FS800DTU联动OneNET平台数据可视化View

目录 1 前言 2 环境搭建 2.1 硬件准备 2.2 软件环境 2.3 硬件连接 3 注册OneNET云平台并建立物模型 3.1 参数获取 3.2 连接OneNET 3.3上报数据 4 数据可视化View 4.1 用户信息获取 4.2 启用数据可视化View 4.3 创建项目 4.4 编辑项目 4.5 新增数据源 4.6 数据过滤器配置 4.6 项…

大模型训练——pycharm连接实验室服务器

一、引言 我们在运行或者复现大佬论文代码的时候&#xff0c;笔记本的算力不够&#xff0c;需要使用实验室的服务器进行运行。可以直接在服务器的终端上执行&#xff0c;但是这样的话代码调试就不方便。而我们可以使用 pycharm 连接到服务器&#xff0c;既方便了代码调试&…

【Linux】进程优先级 | 进程调度(三)

目录 前言&#xff1a; 一、进程优先级&#xff1a; 1.通过nice值修改优先级&#xff1a; 二、进程切换&#xff1a; 三、上下文数据 四、Linux真实调度算法&#xff1a; 五、bitmap位图&#xff1a; 六、命令总结&#xff1a; 总结&#xff1a; 前言&#xff1a; 我…

【C语言】第八期——指针、二维数组与字符串

目录 1 初始指针 2 获取变量的地址 3 定义指针变量、取地址、取值 3.1 定义指针变量 3.2 取地址、取值 4 对指针变量进行读写操作 5 指针变量作为函数参数 6 数组与指针 6.1 指针元素指向数组 6.2 指针加减运算&#xff08;了解&#xff09; 6.2.1 指针加减具体数字…

SpringBoot——生成Excel文件

在Springboot以及其他的一些项目中&#xff0c;或许我们可能需要将数据查询出来进行生成Excel文件进行数据的展示&#xff0c;或者用于进行邮箱发送进行附件添加 依赖引入 此处demo使用maven依赖进行使用 <dependency><groupId>org.apache.poi</groupId>&…