云备份项目--工具类编写

4. 文件工具类的设计

4.1 整体的类

该类实现对文件进行操作

FileUtil.hpp如下

/*
该类实现对文件进行操作
*/
#pragma once
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <experimental/filesystem>      // c++17 的文件系统库
#include "bundle.h"namespace cloud
{
namespace fs = std::experimental::filesystem;class FileUtil
{
private:std::string _fileName;struct stat _st;        // 用于获取文件的各种属性
public:// 输入一个路径FileUtil(std::string fileName) : _fileName(fileName) {if(stat(_fileName.c_str(), &_st) < 0) {std::cerr << "获取文件属性失败!\nstat(_fileName.c_str(), &_st) error! why: " << strerror(errno) << '\n';// exit(1);}}// 获取文件大小(单位是字节)int64_t getFileSize(){return _st.st_size;      // 返回字节数,有符号的长整型}// 获取文件最后一次修改时间time_t getLastMTime(){return _st.st_mtime;}// 获取文件最后一次访问时间time_t getLastATime(){return _st.st_atime;}// 获得一个路径最后文件的名称,例如/abc/a.txt -> a.txtstd::string getFileName(){ssize_t pos = _fileName.find_last_of('/');if(pos == std::string::npos) {// 没有/,证明这就是一个文件,没有文件夹return _fileName;}// 有/,要截取字符串return _fileName.substr(pos+1);}// 从pos位置获取len长度的数据(单位是字节),写到s中bool getContentFromPos(std::string *s, size_t pos, size_t len){int64_t fileSz = getFileSize();if(pos + len > fileSz) {// 申请的长度大于文件长度std::cerr << "Bad size!\nbool getContentFromPos(std::string *s, size_t pos, size_t len)\n";return false;}// 用来读取文件std::ifstream ifile(_fileName, std::ios::binary);// 是否打开成功if(ifile.is_open() == false) {std::cerr << "Open file error!\nbool getContentFromPos(std::string *s, size_t pos, size_t len)\n";ifile.close();return false;}// 读取文件内容ifile.seekg(pos, std::ios::beg);s->resize(len);     ifile.read((char*)(s->c_str()), len);// 检测这个流的状态是否okif(ifile.good() == false) {std::cerr << "read file error!\nbool getContentFromPos(std::string *s, size_t pos, size_t len)\n";ifile.close();return false;}return true;}// 获取文件的所有内容,写到s中bool getFullContent(std::string *s) {// 调用getContentFromPos()return getContentFromPos(s, 0, getFileSize());}// 将字符串s的内容写入到文件中bool setContent(const std::string& s){// 用来像文件写入std::ofstream ofile(_fileName, std::ios::binary);// 是否打开成功if(ofile.is_open() == false) {std::cerr << "Open file error!\nbool setContent(const std::string& s)\n";ofile.close();return false;}ofile.write((char*)s.c_str(), s.size());// 检测这个流的状态是否okif(ofile.good() == false) {std::cerr << "write file error!\nbool setContent(const std::string& s)\n";ofile.close();return false;}return true;}// 压缩,packName是压缩包的名字bool compresss(const std::string& packName){// 先读取文件内容std::string content;if(getFullContent(&content) == false) {std::cerr << "bool compresss(const std::string& packName) get content error!\n";return false;}// 压缩文件内容,这里使用LZIP压缩格式std::string packContent = bundle::pack(bundle::LZIP, content);cloud::FileUtil newFile(packName);// 将内容写到新的文件if(newFile.setContent(packContent) == false) {std::cerr << "bool compresss(const std::string& packName) set content error!\n";return false;}return true;}// 解压,fileName是解压后新文件的名字bool unCompress(const std::string& fileName){// 先读取文件内容std::string content;if(getFullContent(&content) == false) {std::cerr << "bool unCompress(const std::string& packName) get content error!\n";return false;}// 解压文件内容std::string unpackContent = bundle::unpack(content);cloud::FileUtil newFile(fileName);// 将内容写到新的文件if(newFile.setContent(unpackContent) == false) {std::cerr << "bool unCompresss(const std::string& packName) set content error!\n";return false;}return true;}// 判断文件是否存在,存在返回truebool exits(){return fs::exists(_fileName);}// 创建目录,创建成功返回truebool createDir(){// 如果该文件存在了,就直接返回trueif(exits())    return true;return fs::create_directories(_fileName);}// 扫描文件夹下的文件,放到数组中bool scanDir(std::vector<std::string> *array){   for (const fs::directory_entry& entry : fs::directory_iterator(_fileName)) {if(fs::is_directory(entry) == true) {// 如果是目录的话,跳过,该函数只扫描一般文件continue;}array->push_back(entry.path().relative_path().string());}   }
};}

makefile如下

cloud : Cloud.cpp bundle.cpp FileUtil.hppg++ $^ -o $@ -lpthread -lstdc++fs.PHONY : clean
clean:rm -f cloud

4.2 测试

4.2.1 测试获取文件属性功能

Cloud.cpp

#include "FileUtil.hpp"// 测试获取文件属性功能
void testFileUtil(const std::string& s)
{cloud::FileUtil f(s);printf("文件大小: %ld\n", f.getFileSize());printf("文件最后一次修改时间: %ld\n", f.getLastMTime());printf("文件最后一次访问时间: %ld\n", f.getLastATime());printf("获得一个路径最后文件的名称: %s\n", f.getFileName().c_str());
}int main(int argc, char* argv[])
{if(argc != 2) {std::cerr << "usage error!\n"; return -1;}testFileUtil(argv[1]);return 0;
}

结果如下

lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud test.txt 
文件大小: 28
文件最后一次修改时间: 1734504144
文件最后一次访问时间: 1734504157
获得一个路径最后文件的名称: test.txt
---------------------------------------------------------------------------
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud ../../lib/bundle/README.md 
文件大小: 16571
文件最后一次修改时间: 1734185453
文件最后一次访问时间: 1734185453
获得一个路径最后文件的名称: README.md
---------------------------------------------------------------------------
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud aaaa.txt
获取文件属性失败!
stat(_fileName.c_str(), &_st) error! why: No such file or directory

4.2.2 测试文件读写功能

void testFileUtil2(const std::string& fileName)
{cloud::FileUtil f(fileName);std::string s;f.getFullContent(&s);// std::cout << s;cloud::FileUtil of("writeTest.txt");        // 打开一个名为writeTest.txt的文件,没有则创建of.setContent(s);
}int main(int argc, char* argv[])
{if(argc != 2) {std::cerr << "usage error!\n"; return -1;}testFileUtil2(argv[1]);return 0;
}
目前有个文件test.txt
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ cat test.txt 
abcdefghigklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
---------------------------------------------------------------------------
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud test.txt 
获取文件属性失败!
stat(_fileName.c_str(), &_st) error! why: No such file or directory
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ll
total 52
drwxrwxr-x  2 lyf lyf  4096 Dec 18 16:20 ./
drwxrwxr-x 23 lyf lyf  4096 Dec 18 11:31 ../
-rwxrwxr-x  1 lyf lyf 24144 Dec 18 16:20 cloud*
-rw-rw-r--  1 lyf lyf   969 Dec 18 16:16 Cloud.cpp
-rw-rw-r--  1 lyf lyf  3516 Dec 18 16:20 FileUtil.hpp
-rw-rw-r--  1 lyf lyf    67 Dec 18 16:14 makefile
-rw-rw-r--  1 lyf lyf    53 Dec 18 16:14 test.txt
-rw-rw-r--  1 lyf lyf    53 Dec 18 16:20 writeTest.txt
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ cat writeTest.txt 
abcdefghigklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ

4.2.3 测试压缩和解压缩功能

lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud bundle.cpp 
获取文件属性失败!
stat(_fileName.c_str(), &_st) error! why: No such file or directory
获取文件属性失败!
stat(_fileName.c_str(), &_st) error! why: No such file or directory
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ls -lh
total 15M
-rw-rw-r-- 1 lyf lyf 5.4M Dec 18 19:14 bundle.cpp
-rw-rw-r-- 1 lyf lyf 668K Dec 18 19:34 bundle.cpp.lz
-rw-rw-r-- 1 lyf lyf  29K Dec 18 19:14 bundle.h
-rwxrwxr-x 1 lyf lyf 3.3M Dec 18 19:33 cloud
-rw-rw-r-- 1 lyf lyf 1.3K Dec 18 19:33 Cloud.cpp
-rw-rw-r-- 1 lyf lyf 5.0K Dec 18 19:24 FileUtil.hpp
-rw-rw-r-- 1 lyf lyf  101 Dec 18 19:28 makefile
-rw-rw-r-- 1 lyf lyf 5.4M Dec 18 19:34 newname.cpp
-rw-rw-r-- 1 lyf lyf   23 Dec 18 19:32 test.txt
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ md5sum bundle.cpp
4cb64c7a8354c82402dd6fe080703650  bundle.cpp
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ md5sum newname.cpp 
4cb64c7a8354c82402dd6fe080703650  newname.cpp

4.2.4 测试目录功能

// 测试目录操作
void testFileUtil4(const std::string& fileName)
{cloud::FileUtil f(fileName);f.createDir();      // 创建一个文件夹std::vector<std::string> array;f.scanDir(&array);// 打印目录下的文件内容for(const auto& e : array) {std::cout << e << '\n';}
}
# 获取文件夹下的所有文件
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ls
bundle.cpp  bundle.h  cloud  Cloud.cpp  FileUtil.hpp  makefile  test.txt
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud test
获取文件属性失败!
stat(_fileName.c_str(), &_st) error! why: No such file or directory
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ls
bundle.cpp  bundle.h  cloud  Cloud.cpp  FileUtil.hpp  makefile  test  test.txt
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ cd test/
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份/test$ ll
total 8
drwxrwxr-x 2 lyf lyf 4096 Dec 18 21:53 ./
drwxrwxr-x 3 lyf lyf 4096 Dec 18 21:53 ../
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份/test$ touch a.txt
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份/test$ touch b.cc
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份/test$ touch c.java
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份/test$ touch d.python
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份/test$ cd ../
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud ./test
./test/c.java
./test/d.python
./test/b.cc
./test/a.txt

5. Json工具类的设计

5.1 整体的类

#pragma once
#include <iostream>
#include <jsoncpp/json/json.h>
#include <string>
#include <sstream>
#include <memory>namespace cloud
{
class JsonUtil
{
public:// 将root的序列化结果保存在str中static bool serialize(const Json::Value& root, std::string* str){Json::StreamWriterBuilder swb;std::unique_ptr<Json::StreamWriter> ps(swb.newStreamWriter());std::stringstream ss;if (ps->write(root, &ss) != 0) {std:: cerr << "write error!\nstatic bool serialize(const Json::Value& root, std::string* str)\n";return false;} *str = ss.str();return true;}// 将str的序列化结果保存在root中static bool unserialize(const std::string& str, Json::Value* root){Json::CharReaderBuilder crb;std::unique_ptr<Json::CharReader> ps(crb.newCharReader());std::string errs;if (ps->parse(str.c_str(), str.c_str() + str.size(), root, &errs) == false) {std::cerr << "parse error!, why: " << str  << "\nstatic bool unserialize(const std::string& str, Json::Value* root)\n";return false;}return true;}
};
}

5.2 测试序列化工具类

// 测试JsonUtil
void testJsonUtil()
{/* 序列化 */std::string name = "zhangsan";int age = 20;int scores[] = {80, 90, 100};// 给数据对象类添加数据Json::Value value;value["name"] = name;value["age"] = age;value["score"].append(scores[0]);value["score"].append(scores[1]);value["score"].append(scores[2]);std::string str;cloud::JsonUtil::serialize(value, &str);printf("序列化结果:\n %s\n%s\n", str.c_str(), "========================================");Json::Value oValue;/* 反序列化, 将s反序列化*/cloud::JsonUtil::unserialize(str, &oValue);printf("反序列化结果: \nname: %s\nage: %d\n", (oValue["name"].asString()).c_str(), oValue["age"].asInt());for(int i = 0; i < 3; ++i) {printf("成绩%d: %d\n", i, oValue["score"][i].asInt());}
}
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud 
序列化结果:{"age" : 20,"name" : "zhangsan","score" : [80,90,100]
}
========================================
反序列化结果: 
name: zhangsan
age: 20
成绩0: 80
成绩1: 90
成绩2: 100

6. 服务端所用到的配置信息

6.1 json格式的配置信息

  • 服务器访问 IP 地址

  • 服务器访问端⼝

  • 热点判断时间(多长时间没有被访问的文件属于非热点文件)

  • URL路径前缀(如http://www.example.com/path/to/file的路径前缀是/path/

  • 压缩包后缀名称 (在文件原名后面加上该后缀)

  • 上传⽂件存放路径(上传后的文件储存在服务器的哪个文件夹下)

  • 压缩⽂件存放路径(压缩文件储存在服务器的哪个文件夹下)

  • 服务端备份信息存放文件名 (可以通过数据库存放)

使用json格式存放,下面是一个实例。cloud.conf

TODO: 构造函数出错返回?
将bundle变成一个库

{"serverIp" : "124.70.203.1","serverPort" : 9000,"hotTime" : 30,"pathPre" : "/listShow/","rarSuf" : ".lz","ulPath" : "./files","rarPath" : "./rars","backups" : "./backups.data"
}

6.2 加载配置信息类

6.2.1 完整的类

使用单例模式。config.hpp

/* 用于加载配置文件 */
#include "FileUtil.hpp"
#include "JsonUtil.hpp"
#include <mutex>
#define CONF_PATH "./cloud.conf"namespace cloud
{
class Config
{
private:static Config* _instance;static std::mutex _mtx;Config(const Config& c) = delete;Config& operator=(const Config& c) = delete;Config() {if(loadFiles() == false)    delInstance();}// 从配置文件中加载数据,放到各个属性中bool loadFiles(){   // 打开文件cloud::FileUtil fu(CONF_PATH);std::string content;if(fu.getFullContent(&content) == false) {std::cerr << "getFullContent error!\nbool loadFiles()\n";return false;}// json转换Json::Value root;if(cloud::JsonUtil::unserialize(content, &root) == false) {std::cerr << "unserialize error!\nbool loadFiles()\n";return false;}// 初始化_serverIp = root["serverIp"].asString();_serverPort = root["serverPort"].asInt();_hotTime = root["hotTime"].asInt64();_pathPre = root["pathPre"].asString();_rarSuf = root["rarSuf"].asString();_ulPath = root["ulPath"].asString();_rarPath = root["rarPath"].asString();_backups = root["backups"].asString();return true;}
private:std::string _serverIp;  // 服务器访问 IP 地址  int _serverPort;        // 服务器访问端⼝ std::time_t _hotTime;   // 热点判断时间std::string _pathPre;   // URL路径前缀std::string _rarSuf;    // 压缩包后缀名称std::string _ulPath;    // 上传文件存放的路径std::string _rarPath;   // 压缩文件存放的路径std::string _backups;   // 备份文件
public:// 获取实例static Config* getInstance(){if(_instance == nullptr) {      // _instance为null时,才有加锁解锁的必要。外面多加一层判断可以防止每次getInstance()时都要申请锁std::unique_lock<std::mutex> lck(_mtx);if(_instance == nullptr) {_instance = new Config();}}return _instance;}// 删除实例static void delInstance(){if(_instance != nullptr) {std::cout << "log: static void delInstance()\n";delete _instance;_instance = nullptr;}}std::string getServerIp() { return _serverIp; }int getServerPort() { return _serverPort; }std::time_t getHotTime() { return _hotTime; }std::string getPathPre() { return _pathPre; }std::string getRarSuf() { return _rarSuf; }std::string getUlPath() { return _ulPath; }std::string getRarPath() { return _rarPath; }std::string getBackups() { return _backups; } 
};
Config* Config::_instance = nullptr;
std::mutex Config::_mtx;
}

6.2.2 测试

// 测试Config.hpp
void testConfig()
{   cloud::Config* cof = cloud::Config::getInstance();std::cout << cof->getServerIp() << '\n';std::cout << cof->getServerPort() << '\n';std::cout << cof->getHotTime() << '\n';std::cout << cof->getPathPre() << '\n';std::cout << cof->getRarSuf() << '\n';std::cout << cof->getUlPath() << '\n';std::cout << cof->getRarPath() << '\n';std::cout << cof->getBackups() << '\n';
}
lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud 
124.70.203.1
9000
30
/listShow/
.lz
./files
./rars
./backups.data

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

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

相关文章

51c大模型~合集94

我自己的原文哦~ https://blog.51cto.com/whaosoft/12897659 #D(R,O) Grasp 重塑跨智能体灵巧手抓取&#xff0c;NUS邵林团队提出全新交互式表征&#xff0c;斩获CoRL Workshop最佳机器人论文奖 本文的作者均来自新加坡国立大学 LinS Lab。本文的共同第一作者为上海交通大…

【大学英语】英语范文十八篇,书信,议论文,材料分析

关注作者了解更多 我的其他CSDN专栏 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数字信号处理 光电融合集成电路…

一起学Git【第一节:Git的安装】

Git是什么&#xff1f; Git是什么&#xff1f;相信大家点击进来已经有了初步的认识&#xff0c;这里就简单的进行介绍。 Git是一个开源的分布式版本控制系统&#xff0c;由Linus Torvalds创建&#xff0c;用于有效、高速地处理从小到大的项目版本管理。Git是目前世界上最流行…

消息队列 Kafka 架构组件及其特性

Kafka 人们通常有时会将 Kafka 中的 Topic 比作队列&#xff1b; 在 Kafka 中&#xff0c;数据是以主题&#xff08;Topic&#xff09;的形式组织的&#xff0c;每个 Topic 可以被分为多个分区&#xff08;Partition&#xff09;。每个 Partition 是一个有序的、不可变的消息…

《Mycat核心技术》第06章:Mycat问题处理总结

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章汇总&#xff1a;https://binghe.gitcode.host/md/all/all.html 星球项目地址&#xff1a;https://binghe.gitcode.host/md/zsxq/introduce.html 沉淀&#xff0c…

【day11】面向对象编程进阶(继承)

概述 本文深入探讨面向对象编程的核心概念&#xff0c;包括继承、方法重写、this和super关键字的使用&#xff0c;以及抽象类和方法的定义与实现。通过本文的学习&#xff0c;你将能够&#xff1a; 理解继承的优势。掌握继承的使用方法。了解继承后成员变量和成员方法的访问特…

随手记:小程序兼容后台的wangEditor富文本配置链接

场景&#xff1a; 在后台配置wangEditor富文本&#xff0c;可以文字配置链接&#xff0c;图片配置链接&#xff0c;产生的json格式为&#xff1a; 例子&#xff1a; <h1><a href"https://uniapp.dcloud.net.cn/" target"_blank"><span sty…

6.8 Newman自动化运行Postman测试集

欢迎大家订阅【软件测试】 专栏&#xff0c;开启你的软件测试学习之旅&#xff01; 文章目录 1 安装Node.js2 安装Newman3 使用Newman运行Postman测试集3.1 导出Postman集合3.2 使用Newman运行集合3.3 Newman常用参数3.4 Newman报告格式 4 使用定时任务自动化执行脚本4.1 编写B…

工具环境 | 工具准备

搭建一套验证环境需要的工具如下&#xff1a; 虚拟机&#xff1a;推荐virtualbox ubuntu VM好用&#xff0c;但是免费的好像木有了&#xff0c;ubuntu界面版更加容易上手。 网上找安装教程即可&#xff0c;注意实现文件共享、复制粘贴等功能。 EDA&#xff1a;VCS Veridi 工…

计算机网络之王道考研读书笔记-2

第 2 章 物理层 2.1 通信基础 2.1.1 基本概念 1.数据、信号与码元 通信的目的是传输信息。数据是指传送信息的实体。信号则是数据的电气或电磁表现&#xff0c;是数据在传输过程中的存在形式。码元是数字通信中数字信号的计量单位&#xff0c;这个时长内的信号称为 k 进制码…

ROS2学习配套C++知识

第3章 订阅和发布——话题通信探索 3.3.1 发布速度控制海龟画圆 std::bind cstd::bind绑定成员函数时&#xff0c;需要加上作用域以及取址符号 因为不会将成员函数隐式的转换成指针&#xff0c;因此需要加&符号&#xff1b; 后面的第一个参数必须跟具体对象&#xff0c;c…

法规标准-C-NCAP评测标准解析(2024版)

文章目录 什么是C-NCAP&#xff1f;C-NCAP 评测标准C-NCAP评测维度三大维度的评测场景及对应分数评星标准 自动驾驶相关评测场景评测方法及评测标准AEB VRU——评测内容(测什么&#xff1f;)AEB VRU——评测方法(怎么测&#xff1f;)车辆直行与前方纵向行走的行人测试场景&…

第十七届山东省职业院校技能大赛 中职组“网络安全”赛项任务书正式赛题

第十七届山东省职业院校技能大赛 中职组“网络安全”赛项任务书-A 目录 一、竞赛阶段 二、竞赛任务书内容 &#xff08;一&#xff09;拓扑图 &#xff08;二&#xff09;模块A 基础设施设置与安全加固(200分) &#xff08;三&#xff09;B模块安全事件响应/网络安全数据取证/…

mlr3机器学习AUC的置信区间提取

如果你在mlr3拿到机器学习的预测数据 ROC 过程原理探索 假设数据 df <- data.frame(Airis$Sepal.Length, groupsample(x c(0,1),size 150,replace T)) 分组为 0,1 # 变量A为连续性变量 library(pROC) roc_obj <- roc(df g r o u p , d f group, df group,dfA, le…

Halcon例程代码解读:安全环检测(附源码|图像下载链接)

安全环检测核心思路与代码详解 项目目标 本项目的目标是检测图像中的安全环位置和方向。通过形状匹配技术&#xff0c;从一张模型图像中提取安全环的特征&#xff0c;并在后续图像中识别多个实例&#xff0c;完成检测和方向标定。 实现思路 安全环检测分为以下核心步骤&…

Java——多线程进阶知识

目录 一、常见的锁策略 乐观锁VS悲观锁 读写锁 重量级锁VS轻量级锁 总结&#xff1a; 自旋锁&#xff08;Spin Lock&#xff09; 公平锁VS非公平锁 可重入锁VS不可重入锁 二、CAS 何为CAS CAS有哪些应用 1&#xff09;实现原子类 2&#xff09;实现自旋锁 CAS的ABA…

ubuntu18.04升级到ubuntu20.04

为了使用qt6&#xff0c;在ubuntu18.04上各种折腾失败&#xff0c;无奈只能升级到ubuntu20.04, 按照网上的教程没成功。自己摸索了 lsb_release -a df -h sudo apt update sudo apt upgrade -y sudo apt dist-upgrade -y sudo apt autoremove -y sudo apt clean sudo apt inst…

【Blender】【源码详解】BLI_mesh_boolean 实现详解

1. 背景&#xff1a; 最近因为项目需要&#xff0c;需要阅读 Blender 中关于 mesh boolean 的源码&#xff1b;因此&#xff0c;对 blender 中的 mesh boolean 源码进行解读&#xff1b; Github 上源码下载很慢&#xff0c;一般使用 Gitee: gitee Blender 源码 2. Mesh Boole…

qcow2镜像大小压缩

本文拟对qcow2进行压缩进行简单介绍 背景 qcow2镜像在使用一段时间后&#xff0c;总是会不断膨胀变大&#xff0c;所以在导出分享时一般都需要进行压缩以缩减占用空间。 清除空洞 qcow2方式也有稀疏的问题&#xff0c;在磁盘级别上看&#xff0c;镜像会有大量连续的相同空洞…

达梦 本地编码:PG_GBK, 导入文件编码:PG_UTF8错误

问题 达梦 本地编码&#xff1a;PG_GBK, 导入文件编码&#xff1a;PG_UTF8错误 解决 右键管理服务器 查看配置 新建一个数据库实例&#xff0c;配置跟之前的保持一致 新建一个用户&#xff0c;跟以前的用户名一样 在用户上&#xff0c;右键导入&#xff0c;选择dmp的位置 导…