一般卖机械行业的做哪些网站/小网站怎么搜关键词
前面讲了很多Qt的文件操作,文件操作自然就包括压缩与解压缩文件了,正好最近项目里要用到压缩以及解压缩文件,所以就研究了一下Qt如何压缩与解压缩文件。
QZipReader/QZipWriter
QZipReader 和 QZipWriter 类提供了用于读取和写入 ZIP 格式文件的功能,这个是qt自带的,试了一下个人感觉并不好用。
首先QZipReader/QZipWriter是在Qt5.14之后才引入的,而且使用需要用到gui-private这个模块,搜了一下,在 Qt 中,gui-private 模块是 Qt 框架中的一个私有模块,通常不是为公共使用而设计的。该模块包含了一些 Qt GUI 框架内部使用的实现细节、私有接口和工具类,而不是为外部开发者提供的公共 API。一般来说,Qt 将其功能模块划分为公共模块和私有模块。公共模块包含了开发者可以直接使用的公共 API,而私有模块则包含了框架内部的实现细节和工具类,这些类通常不应该被外部开发者直接使用。所以才不推荐使用。直接看代码:
首先pro文件包含对应模块:
QT +=gui-private
头文件包含:
#include <QtGui/private/qzipreader_p.h>
#include <QtGui/private/qzipwriter_p.h>
压缩函数:
/*** @brief 压缩文件* @param fileNames 需要压缩的文件绝对路径* @param path 压缩后的文件的绝对路径*/
void zip_compress(const QStringList &fileNames, const QString &path) {QZipWriter *zipWriter = new QZipWriter(path);foreach (const QString &fileName, fileNames) {if (fileName.isEmpty()) continue;QFileInfo fileInfo(fileName);if (!fileInfo.exists()) continue;QFile file(fileName);if (!file.open(QIODevice::ReadOnly)) continue;zipWriter->addFile(fileInfo.fileName(), file.readAll());file.close();}zipWriter->close();if (zipWriter) {delete zipWriter;zipWriter = nullptr;}
}
解压函数:
/*** @brief 解压缩文件* @param fileName 需要解压缩的文件* @param path 解压后文件存放的目录*/
void zip_decompress(const QString &fileName, const QString &path) {if (fileName.isEmpty()) {return;}QFileInfo fileInfo(fileName);if (!fileInfo.exists()) {return;}QZipReader *reader = new QZipReader(fileName);foreach (const QZipReader::FileInfo &info, reader->fileInfoList()) {if (!info.isDir) {QString filePath =QDir::cleanPath(path + QDir::separator() + info.filePath);QFile file(filePath);if (!file.open(QIODevice::WriteOnly)) {continue;}file.write(reader->fileData(info.filePath));file.close();} else {QString dirName =QDir::cleanPath(path + QDir::separator() + info.filePath);QDir dir(dirName);if (!dir.exists()) dir.mkdir(dirName);}}reader->close();if (reader) {delete reader;reader = nullptr;}
}
7z
常用的解压软件比较多,例如winrar、7z、bandzip等等,其中7z是支持命令行形式的,详细命令可以看一下这两篇文章:
7z 命令行详解_7z命令-CSDN博客
前面我的这篇文章:Qt外部调用进程类QProcess的使用_windows qt 调用其它进程-CSDN博客
就介绍过Qt如何通过QProcess调用外部进程,所以可以先安装7z然后使用QProcess调用7z应用程序,通过传参形式来压缩和解压缩文件,直接看代码:
压缩函数:
/*** @brief z7_compress 压缩函数* @param fileNames 需要压缩的文件的绝对路径* @param path 压缩后生成的压缩文件的绝对路径*/
void z7_compress(const QStringList &fileNames, const QString &path) {QProcess process(0);QStringList args;args.append("a");args.append(path);args.append(fileNames);args.append("-mx=3");process.start("7z.exe", args);//注意7z.exe的路径process.waitForStarted();process.waitForFinished();
}
解压缩函数:
/*** @brief z7_decompress 解压缩函数* @param fileName 需要解压缩的压缩包路径* @param path 解压缩后生成的目录*/
void z7_decompress(const QString &fileName, const QString &path) {QProcess process(0);QStringList args;args.append("x");args.append(fileName);args.append("-o" + path);args.append("-aoa");process.start("7z.exe", args);//注意7z.exe的路径process.waitForStarted();process.waitForFinished();
}
ZLib
Qt压缩和解压缩文件也可以借助第三方库,zlib或者libzip,这里只介绍zlib。libzip有兴趣的也可以自己下去研究。
zlib 是一个开源的数据压缩库,广泛用于许多应用程序和系统中。以下是关于 zlib 的详细介绍:
-
功能:
- zlib 库提供了数据压缩和解压缩的功能,支持使用 DEFLATE 算法进行数据压缩。
- zlib 提供了简单的 API,易于集成到各种应用程序中。
- zlib 还支持在压缩数据中添加校验和,以确保数据的完整性。
-
特点:
- 高效性:zlib 使用 DEFLATE 算法进行数据压缩,具有较高的压缩比和压缩速度。
- 跨平台性:zlib 可以在各种操作系统上运行,包括 Windows、Linux、macOS 等。
- 开源性:zlib 是一个开源库,使用 zlib 的应用程序可以遵循 zlib 的开源许可协议。
-
使用场景:
- zlib 可用于在应用程序中对数据进行压缩,减小数据传输和存储的大小。
- zlib 还可用于处理压缩文件格式,如 ZIP、PNG、HTTP 的 gzip 压缩等。
- zlib 也常用于实时数据流的压缩,如网络传输中的数据压缩。
-
API:
- zlib 提供了一组简单的 C 函数来进行数据压缩和解压缩,如
compress()
,uncompress()
,deflate()
,inflate()
等。 - zlib 还提供了一些工具函数和数据结构,如
z_stream
结构体用于维护压缩和解压缩的状态。
- zlib 提供了一组简单的 C 函数来进行数据压缩和解压缩,如
首先需要下载zlib源码,zlib官网,下载之后解压然后准备编译:
使用Cmake:
注意cmake对应vs,我电脑vs装的是VS2022,所以我这里选的是2022。
然后先Configure再Generate等待完成:
然后进入生成目录使用VS打开对应工程文件:
编译生成:
注意debug和relase版本以及平台。
对应生成的库文件以及导入库文件:
建立这样的一个文件目录结构,然后准备在代码中使用:
注意:zconf.h这个文件在cmake生成的文件目录里面 。dll动态库文件放在可执行文件同级目录下。
在工程文件中引入对应头文件以及库文件:
#引入zlib头文件和库
INCLUDEPATH += $PWD/zlib/includewin32 {LIBS += -L$$PWD/zlib/libCONFIG(release, debug|release) {LIBS += -lzlib}CONFIG(debug, debug|release) {LIBS += -lzlibd}
}
试一下zlib的压缩以及解压字符串函数。
压缩字符串:
static QByteArray compress(const QByteArray &data) {z_stream zs;memset(&zs, 0, sizeof(zs));if (deflateInit(&zs, Z_BEST_COMPRESSION) != Z_OK) { return QByteArray(); }zs.next_in = (Bytef *)data.constData();zs.avail_in = data.size();int ret;char outbuffer[32768];QByteArray outstring;do {zs.next_out = reinterpret_cast<Bytef *>(outbuffer);zs.avail_out = sizeof(outbuffer);ret = deflate(&zs, Z_FINISH);if (outstring.size() < zs.total_out) {outstring.append(outbuffer, zs.total_out - outstring.size());}} while (ret == Z_OK);deflateEnd(&zs);if (ret != Z_STREAM_END) { return QByteArray(); }return outstring;
}
解压缩字符串:
static QByteArray decompress(const QByteArray &data) {z_stream zs;memset(&zs, 0, sizeof(zs));if (inflateInit(&zs) != Z_OK) { return QByteArray(); }zs.next_in = (Bytef *)data.constData();zs.avail_in = data.size();int ret;char outbuffer[32768];QByteArray outstring;do {zs.next_out = reinterpret_cast<Bytef *>(outbuffer);zs.avail_out = sizeof(outbuffer);ret = inflate(&zs, 0);if (outstring.size() < zs.total_out) {outstring.append(outbuffer, zs.total_out - outstring.size());}} while (ret == Z_OK);inflateEnd(&zs);if (ret != Z_STREAM_END) { return QByteArray(); }return outstring;
}
测试压缩一个长字符串:
zlib的压缩与解压缩文件目前我网上搜的只能压缩和解压缩单个的,多个的目前没有找到,简单看一下压缩和解压缩的函数。
bool compress(const QString &fileName, const QString &zipFileName) {QFile inputFile(fileName);if (!inputFile.open(QIODevice::ReadOnly)) { return false; }gzFile zipFile = gzdopen(inputFile.handle(), "wb");if (!zipFile) { return false; }char buffer[1024];int bytesRead;while ((bytesRead = inputFile.read(buffer, sizeof(buffer))) > 0) {gzwrite(zipFile, buffer, bytesRead);}gzclose(zipFile); // 关闭文件句柄inputFile.close(); // 关闭输入文件return true;
}bool decompress(const QString &zipFileName, const QString &fileName) {QFile inputFile(zipFileName);if (!inputFile.open(QIODevice::ReadOnly)) { return false; }QFile outputFile(fileName);if (!outputFile.open(QIODevice::WriteOnly)) { return false; }gzFile zipFile = gzdopen(inputFile.handle(), "rb");if (!zipFile) { return false; }char buffer[1024];int bytesRead;while ((bytesRead = gzread(zipFile, buffer, sizeof(buffer))) > 0) {if (outputFile.write(buffer, bytesRead) != bytesRead) { return false; }}gzclose(zipFile);inputFile.close();outputFile.close();return true;
}
那如果要压缩多个文件怎么办?这里可以使用QuaZip。
QuaZip
QuaZIP 是一个用于 Qt 框架的 C++ 库,它提供了对 ZIP 归档文件的读写功能。QuaZIP 是基于 zlib 和 minizip 库的封装,使得在 Qt 项目中可以方便地处理 ZIP 文件。也就是说QuaZIP是基于zlib的,使用QuaZIP的前提是已经编译好了zlib,zlib的编译前面已经讲了。这里直接开始讲QuaZIP的编译与使用。
首先下载QuaZIP,QuaZIP官网。下载之后进行解压:
可以看到里面有pro文件也有vs工程文件也有CMakeLists.txt文件,我们直接使用QtCreator来进行编译。首先因为QuaZIP依赖zlib,所以把刚刚编译的zlib文件放进来:
这个文件夹结构跟刚刚一样。
我们只编译库,所以进到这个目录:
把对应头文件放进来:
对应工程文件添加引入zlib:
然后开始编译生成对应debug和release版的库文件和导入库文件:
同样方法创建一个quazip文件夹,然后拷贝对应头文件以及导入库文件:
新建一个工程,将对应quazip文件放进工程文件夹内容,然后对应pro文件引入quazip头文件以及相关导入库文件:
INCLUDEPATH += $PWD/quazip/includewin32 {LIBS += -L$$PWD/quazip/libCONFIG(release, debug|release) {LIBS += -lquazip}CONFIG(debug, debug|release) {LIBS += -lquazipd}
}
对应动态库文件放入到可执行文件同级目录下:
注意:别忘了zlib的库文件,我测试用的debug版,所以理论上只放debug版对应zlib和QuaZIP的库文件就够了。
QuaZIP压缩和解压缩文件已经封装好了方法,比如将指定目录内的所有子目录以及文件压缩到指定压缩包内方法:
\param fileCompressed The name of the archive.\param dir The directory to compress.\param recursive Whether to pack the subdirectories as well, orjust regular files.\return true if success, false otherwise.*/static bool compressDir(QString fileCompressed, QString dir = QString(), bool recursive = true);
对应的解压方法:
/**\param fileCompressed The name of the archive.\param dir The directory to extract to, the current directory ifleft empty.\return The list of the full paths of the files extracted, empty on failure.*/static QStringList extractDir(QString fileCompressed, QString dir = QString());/// Get the file list.
写一个简单的测试程序。
界面ui:
头文件:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACEclass MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_openDir_clicked();void on_compress_clicked();void on_selectZip_clicked();void on_decompress_clicked();private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
源文件:
#include "mainwindow.h"
#include "quazip/include/JlCompress.h"
#include "ui_mainwindow.h"#include <QDebug>
#include <QDir>
#include <QFileDialog>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);
}MainWindow::~MainWindow() { delete ui; }void MainWindow::on_openDir_clicked() {QString dirPath =QFileDialog::getExistingDirectory(nullptr, QString(), QString());ui->dePath->setText(dirPath);
}void MainWindow::on_compress_clicked() {if (ui->dePath->text().isEmpty()) return;QDir deDir(ui->dePath->text());if (!deDir.exists()) return;if (deDir.isEmpty()) return;QString zipFileName = QDir::cleanPath(deDir.absolutePath() + QDir::separator() + deDir.dirName() + ".zip");bool r = JlCompress::compressDir(zipFileName, deDir.absolutePath());if (r)qDebug() << "compress success";elseqDebug() << "compress fail";
}void MainWindow::on_selectZip_clicked() {QString zipFileName = QFileDialog::getOpenFileName(nullptr, QString(), QString(), "Code Files (*.zip *.7z)");if (zipFileName.isEmpty()) return;ui->zipPath->setText(zipFileName);
}void MainWindow::on_decompress_clicked() {if (ui->zipPath->text().isEmpty()) return;QString zipFileName = ui->zipPath->text();if (!QFile::exists(zipFileName)) return;QFileInfo zipFileInfo(zipFileName);QString deDirPath =QDir::cleanPath(zipFileInfo.absolutePath() + QDir::separator() +zipFileInfo.completeBaseName());QDir deDir(deDirPath);if (!deDir.exists()) QDir().mkpath(deDirPath);QStringList fileList = JlCompress::extractDir(zipFileInfo.absoluteFilePath(),deDir.absolutePath());if (!fileList.isEmpty())qDebug() << "decompress success";elseqDebug() << "decompress fail";
}
测试一下:
没有问题,这个测试文件的代码我会上传,仅供参考,我编译的zlib以及QuaZIP的库文件也在里面,建议自己编译,因为平台或者编译软件可能与我不同,我的环境是Windows,VS2022,Qt5.15.2。
其他相关压缩以及解压缩这里就不做介绍了,有兴趣的可以下去自己研究一下。
相关文章:

Qt 压缩/解压文件
前面讲了很多Qt的文件操作,文件操作自然就包括压缩与解压缩文件了,正好最近项目里要用到压缩以及解压缩文件,所以就研究了一下Qt如何压缩与解压缩文件。 QZipReader/QZipWriter QZipReader 和 QZipWriter 类提供了用于读取和写入 ZIP 格式文…...

【leetcode刷题之路】面试经典150题(8)——位运算+数学+一维动态规划+多维动态规划
文章目录 20 位运算20.1 【位运算】二进制求和20.2 【位运算】颠倒二进制位20.3 【位运算】位1的个数20.4 【位运算】只出现一次的数字20.5 【哈希表】【位运算】只出现一次的数字 II20.6 【位运算】数字范围按位与 21 数学21.1 【双指针】回文数21.2 【数学】加一21.3 【数学】…...

JetBrains全家桶激活,分享 WebStorm 2024 激活的方案
大家好,欢迎来到金榜探云手! WebStorm公司简介 JetBrains 是一家专注于开发工具的软件公司,总部位于捷克。他们以提供强大的集成开发环境(IDE)而闻名,如 IntelliJ IDEA、PyCharm、和 WebStorm等。这些工具…...

Sublime 彻底解决中文乱码
1. 按ctrl,打开Console,输入如下代码: import urllib.request,os; pf Package Control.sublime-package; ipp sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHand…...

复旦大学EMBA校友出席两会建言献策助力中国发展
阳春三月,备受瞩目的全国两会如期召开。期间,复旦大学EMBA多位校友作为第十四届全国人民代表大会代表、第十四届全国政协委员与全国各地代表共商国是。 无论是作为大型央企负责人,还是作为科创企业的中坚力量,复旦大学EM…...

virtualbox导入vdi
新建虚拟机 点击新建 输入新建属性 配置cpu和内存 虚拟硬盘 这里选择已有的vdi文件 摘要 这里点击完成 虚拟机添加成功 点击启动,启动虚拟机 注意 这个时候的ip,还是以前镜像的ip,如果两个镜像一起启动,则需要修 改ip地…...

【信号处理】基于DGGAN的单通道脑电信号增强和情绪检测(tensorflow)
关于 情绪检测,是脑科学研究中的一个常见和热门的方向。在进行情绪检测的分类中,真实数据不足,经常导致情绪检测模型的性能不佳。因此,对数据进行增强,成为了一个提升下游任务的重要的手段。本项目通过DCGAN模型实现脑…...

使用 Docker Compose 部署 Spring Boot 应用
使用 Docker Compose 部署 Spring Boot 应用 第一步:创建 Spring Boot 应用的 Dockerfile 在您的 Spring Boot 项目根目录中创建一个 Dockerfile。 编辑 Dockerfile,添加以下内容: # 基础镜像使用 OpenJDK FROM openjdk:11-jdk-slim# 维护者…...

nginx 正向代理 https
问题背景 因为网络环境受限,应用服务器无法直接访问外网,需要前置机上中转一下,这种情况可在应用服务器修改/etc/hosts文件指向前置机,在前置机上的nginx设置四层代理,从而出站。 方案 根据How to Use NGINX as an …...

vue3从其他页面跳转页面头部组件菜单el-menu菜单高亮
主要代码 import { ref, onMounted, watch } from vue; const activeIndex ref("/"); const route useRoute();onMounted(() > {updateActiveMenu(); });watch(() > route.path, updateActiveMenu);function updateActiveMenu() {// 根据路由更新activeMenu…...

python 条件循环语句
python 条件循环语句 一、条件控制语句1. Python3 条件控制2. if 语句3. if 嵌套4. match...case5. 注意: 二、循环控制语句1. Python3 循环语句2. while 循环3. 无限循环4. while 循环使用 else 语句5. 简单语句组6. for 语句7. for...else8. break 和 continue 语…...

CIM搭建实现发送消息的效果
目录 背景过程1、下载代码2、进行配置3、直接启动项目4、打开管理界面5、启动web客户端实例项目6、发送消息 项目使用总结 背景 公司项目有许多需要发送即时消息的场景,之前一直采用的是传统的websocket连接,它会存在掉线严重,不可重连&…...

C++第十三弹---内存管理(下)
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】 目录 1、operator new与operator delete函数 1.1、operator new与operator delete函数 2、new和delete的实现原理 2.1、内置类型 2.2、自定义类型 …...

Python爬虫学习完整版
一、什么是爬虫 网络爬虫,是一种按照一定规则,自动抓取互联网信息的程序或者脚本。由于互联网数据的多样性和资源的有限性,根据用户需求定向抓取相关网页并分析也成为如今主流的爬取策略。 1 爬虫可以做什么 你可以爬取网络上的的图片&#…...

JavaScript中的继承方式详解
Question JavaScript实现继承的方式? 包含原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承和ES6 类继承 JavaScript实现继承的方式 在JavaScript中,实现继承的方式多种多样,每种方式都有其优势和适用场景。以下…...

Git基础(23):Git分支合并实战保姆式流程
文章目录 前言准备正常分支合并1. 创建两个不冲突分支2. 将dev合并到test 冲突分支合并1. 制造分支冲突2. 冲突合并 前言 Git分支合并操作 准备 这里先在Gitee创建了一个空仓库,方便远程查看内容。 正常分支合并 1. 创建两个不冲突分支 (1…...

为什么有些前端一直用 div 当按钮,而不是用 button?
1. HTML 中的 <div> 和 <button> 在了解为什么有些前端开发者更喜欢使用 <div> 作为按钮之前,让我们先来了解一下 <div> 和 <button> 标签在 HTML 中的作用和区别。 <div>:是 HTML 中的一个通用容器元素࿰…...

python实战之基础篇(一)
1. 注释 # coding utf-8 # 该注释放到文件第一行, 这个注释告诉python解释器该文件的编码集是UTF-82. 导入语句有三种形式 import <模块名> from <模块名> import <代码元素> from <模块名> import <代码元素> as <代码元素别名>3. 获取…...

第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(补题)
文章目录 1 日期统计2 01串的熵3 冶炼金属4 飞机降落5 接龙数列6 岛屿个数7 子串简写8 整数删除9 景区导游10 砍树 前言:时隔一年,再次做这套题(去年参赛选手),差点道心不稳T_T,故作此补题! 1 日期统计 没写出来&…...

蓝桥杯刷题--python-32
4964. 子矩阵 - AcWing题库 from collections import deque n, m, a, b map(int, input().split()) mod 998244353 nums [] for _ in range(n): nums.append(list(map(int, input().split()))) rmin [[0 for i in range(m)] for i in range(n)] rmax [[0 for i in ran…...

单例模式如何保证实例的唯一性
前言 什么是单例模式 指一个类只有一个实例,且该类能自行创建这个实例的一种创建型设计模式。使用目的:确保在整个系统中只能出现类的一个实例,即一个类只有一个对象。对于频繁使用的对象,“忽略”创建时的开销。特点:…...

IntelliJ IDE 插件开发 | (七)PSI 入门及实战(实现 MyBatis 插件的跳转功能)
系列文章 IntelliJ IDE 插件开发 |(一)快速入门IntelliJ IDE 插件开发 |(二)UI 界面与数据持久化IntelliJ IDE 插件开发 |(三)消息通知与事件监听IntelliJ IDE 插件开发 |(四)来查收…...

【教程】iOS如何抓取HTTP和HTTPS数据包经验分享
📱 在日常的App开发和研发调研中,对各类App进行深入的研究分析时,我们需要借助专业的抓包应用来协助工作。本文将介绍如何使用iOS手机抓包工具来获取HTTP和HTTPS数据包,并推荐一款实用的抓包应用——克魔助手,希望能够…...

基于javaweb(springboot)汽车配件管理系统设计和实现以及文档报告
基于javaweb(springboot)汽车配件管理系统设计和实现以及文档报告 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐…...

Spring Cloud Gateway Server MVC
之前你如果要用spring cloud gateway ,就必须是webflux 的,也就是必须是异步响应式编程。不能和spring mvc 一起使用。现在spring cloud 新出了一个可以不用webflux的gateway。 具体使用mvc的gateway步骤如下 普通的Eureka Client的项目 如果你只是想测…...

建立动态MGRE隧道的配置方法
目录 一、实验拓扑 1.1通用配置 1.1.1地址配置 1.1.2静态缺省指向R5,实现公网互通 1.1.3MGRE协议配置 1.1.4配置静态 二、Shortcut方式 三、Normal方式(非shortcut) 四、总结 一、实验拓扑 下面两种配置方法皆使用静态方式 1.1通用配…...

【MySQL】9. 内置函数
函数 1. 日期函数 获得年月日: mysql> select current_date(); ---------------- | current_date() | ---------------- | 2024-03-23 | ---------------- 1 row in set (0.00 sec)获得时分秒: mysql> select current_time(); ------------…...

芯片工程系列(5)2.5D 3D封装
0 英语缩写 硅通孔(Through Silicon Via,TSV)硅中介层(Silicon Interposer)物理气象沉淀法(Physical Vapor Deposition,PVD)DRIE、CVD、PVD、CMP等设备CoWoS(Chip on Wa…...

KubeSphere简单介绍及安装使用
KubeSphere 概述 官网地址:https://kubesphere.io/zh/ 什么是 kubesphere KubeSphere 是一个开源的多云容器管理平台,旨在简化企业级 k8s 集群的部署、管理和运维。它提供了一个可视化的管理界面,帮助用户更轻松地管理和监控 k8s 集群&…...

Java零基础-集合:Java 8新增的集合操作
哈喽,各位小伙伴们,你们好呀,我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。 我是一名后…...