【lesson8】云备份服务端完整版代码
文章目录
- util.hpp
- config.hpp
- hot.hpp
- data.hpp
- server.hpp
- server.cc
- Makefile
- cloud.conf
util.hpp
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sys/stat.h>
#include <unistd.h>
#include <cstring>
#include <cstdint>
#include <experimental/filesystem>
#include <jsoncpp/json/json.h>
#include <memory>
#include "bundle.h"namespace cloud
{namespace fs = std::experimental::filesystem;class fileUtil{public:fileUtil(std::string filename):_filename(filename){}bool Remove(){if(exists() == false){return true;}remove(_filename.c_str());return true;}size_t fileSize(){struct stat st;int ret = stat(_filename.c_str(), &st);if(ret == -1){std::cout << strerror(errno) << std::endl;return 0;}return st.st_size;}time_t lastModifyTime(){struct stat st;int ret = stat(_filename.c_str(), &st);if(ret == -1){std::cout << strerror(errno) << std::endl;return -1;}return st.st_mtime;}time_t lastAccessTime(){struct stat st;int ret = stat(_filename.c_str(), &st);if(ret == -1){std::cout << strerror(errno) << std::endl;return -1;}return st.st_atime;}std::string fileName(){size_t pos = _filename.find_last_of("/");if(pos == std::string::npos){return _filename;}return _filename.substr(pos + 1);}bool setContent(const std::string &body){std::ofstream ofs;ofs.open(_filename, std::ios::binary);if(ofs.is_open() == false){std::cout << "setContent open failed\n";return false;}ofs.write(&body[0], body.size());if(ofs.good() == false){std::cout << "setContent write failed\n";ofs.close();return false;}ofs.close();return true;}bool getPosLen(std::string *body, size_t pos, size_t len){std::ifstream ifs;if(pos + len > fileSize()){std::cout << "getPosLen failed\n";return false;}ifs.open(_filename, std::ios::binary);if(ifs.is_open() == false){std::cout << "getPosLen open failed\n";return false;}body->resize(len - pos);ifs.read(&(*body)[0], len);if(ifs.good() == false){std::cout << "getPosLen read failed\n";ifs.close();return false;}ifs.close();return true;}bool getContent(std::string *body){size_t n = fileSize();return getPosLen(body, 0, n);}bool exists(){return fs::exists(_filename);}bool createDirectory(){if(exists())return true;return fs::create_directories(_filename);}bool getDirectory(std::vector<std::string> *arry){for(const fs::directory_entry& entry : fs::directory_iterator{_filename}){if(fs::is_directory(entry))continue;arry->push_back(fs::path(entry).relative_path().string());}return true;}bool compress(const std::string &packname){std::string body;getContent(&body);std::string buffer = bundle::pack(bundle::LZIP, body);std::ofstream ofs;ofs.open(packname, std::ios::binary);if(ofs.is_open() == false){std::cout << "compress open failed\n";return false;}ofs.write(&buffer[0], buffer.size());if(ofs.good() == false){std::cout << "compress write failed\n";ofs.close();return false;}ofs.close();return true;}bool uncompress(const std::string &filename){std::string body;getContent(&body);std::string buffer = bundle::unpack(body);std::ofstream ofs;ofs.open(filename, std::ios::binary);if(ofs.is_open() == false){std::cout << "uncompress open failed\n";return false;}ofs.write(&buffer[0], buffer.size());if(ofs.good() == false){std::cout << "uncompress write failed\n";ofs.close();return false;}ofs.close();return true;}private:std::string _filename;};class JsonUtil{public:static bool Serialize(const Json::Value &root, std::string *str){Json::StreamWriterBuilder swb;std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());std::stringstream ss;int ret = sw->write(root, &ss);if(ret != 0){std::cout << "Serialize failed" << std::endl;return false;}*str = ss.str();return true;}static bool UnSerialize(const std::string &str, Json::Value *root){Json::CharReaderBuilder crb;std::unique_ptr<Json::CharReader> cr(crb.newCharReader());std::string errs;bool ret = cr->parse(str.c_str(), str.c_str() + str.size(), root, &errs);if(ret == false){std::cout << "UnSerialize failed " << errs << std::endl;return false;}return true;}};
}
config.hpp
#pragma once
#include <mutex>
#include "util.hpp"
namespace cloud
{
#define CONFIG_FILE "./cloud.conf"class Config{private:Config(){ReadConfigFile();}bool ReadConfigFile(){fileUtil fu(CONFIG_FILE);std::string body; bool ret = fu.getContent(&body);if(ret == false){std::cout << "ReadConfigFile getContent faile" << std::endl;}Json::Value root;ret = cloud::JsonUtil::UnSerialize(body, &root);if(ret == false){std::cout << "ReadConfigFile UnSerialize faile" << std::endl;}_hot_time = root["hot_time"].asInt();_server_port = root["server_port"].asInt();_server_ip = root["server_ip"].asString();_download_prefix = root["download_prefix"].asString();_packfile_suffix = root["packfile_suffix"].asString();_pack_dir = root["pack_dir"].asString();_back_dir = root["back_dir"].asString();_backup_file = root["backup_file"].asString();}public:static Config* getIstance(){if(_instance == nullptr){_mtx.lock();if(_instance == nullptr){_instance = new Config();}_mtx.unlock();}return _instance;}int getHotTime(){return _hot_time;}int getServerPort(){return _server_port;}std::string getServerIp(){return _server_ip;}std::string getDownloadPrefix(){return _download_prefix;}std::string getPackfileSuffix(){return _packfile_suffix;}std::string getPackDir(){return _pack_dir;}std::string getBackDir(){return _back_dir;}std::string getBackupFile(){return _backup_file;}private:static Config* _instance;static std::mutex _mtx;private:int _hot_time;int _server_port;std::string _server_ip;std::string _download_prefix;std::string _packfile_suffix;std::string _pack_dir;std::string _back_dir;std::string _backup_file;};Config* Config::_instance = nullptr;std::mutex Config::_mtx;
} // namespace cloud
hot.hpp
#pragma once
#include <cstdio>
#include <unistd.h>
#include "data.hpp"
extern cloud::dataManager *_data;namespace cloud
{class HotManager{private://非热点文件返回否, 热点文件返回真bool hotJuge(const std::string& filename){fileUtil fu(filename);time_t last_atime = fu.lastAccessTime();time_t cur_time = time(nullptr);if(cur_time - last_atime > _hot_time){return false;}return true;}public:HotManager(){Config* f = Config::getIstance();_back_dir = f->getBackDir();_pack_dir = f->getPackDir();_packfile_suffix = f->getPackfileSuffix();_hot_time = f->getHotTime();fileUtil fu1(_back_dir);fileUtil fu2(_pack_dir);fu1.createDirectory();fu2.createDirectory();}bool runMoudle(){while(true){//std::cout << -1 << std::endl;fileUtil fu(_back_dir);std::vector<std::string> arry;fu.getDirectory(&arry);for(auto& e : arry){if(hotJuge(e)){continue;}BackupInfo info;bool ret = _data->getBifoByRealPath(e, &info);if(ret == false){std::cout << "runMoudle faile" << std::endl;info.NewBackupInfo(e);}fileUtil fu(e);fu.compress(info.pack_path);fu.Remove();info.pack_flag = true;_data->update(info);}usleep(1000);}return true;}private:std::string _back_dir;std::string _pack_dir;std::string _packfile_suffix;int _hot_time;};
}
data.hpp
#pragma once
#include <unordered_map>
#include <pthread.h>
#include "util.hpp"
#include "config.hpp"namespace cloud
{struct BackupInfo{bool pack_flag;size_t file_size;time_t modify_time;time_t access_time;std::string real_path;std::string pack_path;std::string url;bool NewBackupInfo(const std::string& filepath){//std::cout << filepath << std::endl;fileUtil fu(filepath);if(fu.exists() == false){std::cout << "NewBackupInfo fail" << std::endl;return false;}pack_flag = false;//std::cout << fu.fileSize() << std::endl;file_size = fu.fileSize();modify_time = fu.lastModifyTime();access_time = fu.lastAccessTime();real_path = filepath;Config* f = Config::getIstance();std::string packdir = f->getPackDir();std::string packfile_suffix = f->getPackfileSuffix();pack_path = packdir + fu.fileName() + packfile_suffix;std::string download_prefix = f->getDownloadPrefix();url = download_prefix + fu.fileName();return true;}};class dataManager{public:dataManager(){_backup_file = Config::getIstance()->getBackupFile();pthread_rwlock_init(&_rwlock, nullptr);initLoad();}bool initLoad()//初始化程序运行时从文件读取数据{fileUtil fu(_backup_file);if(fu.exists() == false){return true;}std::string body;bool ret = fu.getContent(&body);if(ret == false){std::cout << "InitLoad getContent failed" << std::endl;return false;}Json::Value root;ret = JsonUtil::UnSerialize(body, &root);if(ret == false){std::cout << "InitLoad getContent failed" << std::endl;return false;}for(int i = 0; i < root.size(); i++){BackupInfo info;info.pack_flag = root[i]["pack_flag"].asBool();info.file_size = root[i]["file_size"].asInt64();info.modify_time = root[i]["modify_time"].asInt64();info.access_time = root[i]["access_time"].asInt64();info.real_path = root[i]["real_path"].asString();info.pack_path = root[i]["pack_path"].asString();info.url = root[i]["url"].asString();//_table[info.url] = info;insert(info);} return true;}bool storage() //每次有信息改变则需要持久化存储一次{Json::Value root;for(auto& e : _table){Json::Value tmp;tmp["pack_flag"] = e.second.pack_flag;tmp["file_size"] = (Json::Int64)e.second.file_size;tmp["modify_time"] = (Json::Int64)e.second.modify_time;tmp["access_time"] = (Json::Int64)e.second.access_time;tmp["real_path"] = e.second.real_path;tmp["pack_path"] = e.second.pack_path;tmp["url"] = e.second.url;root.append(tmp);}std::string body;bool ret = JsonUtil::Serialize(root, &body);if(ret == false){std::cout << "Storage Serialize faile" << std::endl;return false;}fileUtil fu(_backup_file);ret = fu.setContent(body);if(ret == false){std::cout << "Storage setContent faile" << std::endl;return false;}return true;}bool insert(const BackupInfo& Info){pthread_rwlock_wrlock(&_rwlock);_table[Info.url] = Info;pthread_rwlock_unlock(&_rwlock);storage();return true;}bool update(const BackupInfo& Info){pthread_rwlock_wrlock(&_rwlock);_table[Info.url] = Info;pthread_rwlock_unlock(&_rwlock);storage();return true;}bool getBifoByUrl(const std::string& url, BackupInfo* Info){//问题这个应该是读者模式锁还是写者模式锁呢?pthread_rwlock_wrlock(&_rwlock);auto ret = _table.find(url);if(ret == _table.end()){pthread_rwlock_unlock(&_rwlock);return false;}*Info = ret->second;pthread_rwlock_unlock(&_rwlock);return true;}bool getBifoByRealPath(const std::string& realPath, BackupInfo* Info){pthread_rwlock_wrlock(&_rwlock);for(auto& e : _table){if(e.second.real_path == realPath){*Info = e.second;pthread_rwlock_unlock(&_rwlock);return true;}}pthread_rwlock_unlock(&_rwlock);return false;}bool getAll(std::vector<BackupInfo> *arry){pthread_rwlock_wrlock(&_rwlock);for(auto& e : _table){arry->push_back(e.second);}pthread_rwlock_unlock(&_rwlock);return true;}~dataManager(){pthread_rwlock_destroy(&_rwlock);}private:std::string _backup_file;pthread_rwlock_t _rwlock;std::unordered_map<std::string, BackupInfo> _table;};
}
server.hpp
#pragma once
#include "data.hpp"
#include "httplib.h"extern cloud::dataManager *_data;
namespace cloud
{class serevr{private:static void upLoad(const httplib::Request& rq, const httplib::Response& rp){bool ret = rq.has_file("file");if(ret == false){return ;}const auto& file = rq.get_file_value("file");std::string real_path = _back_dir + fileUtil(file.filename).fileName();fileUtil fu(real_path);fu.setContent(file.content);BackupInfo info;info.NewBackupInfo(real_path);_data->insert(info);return;}static std::string timeToString(time_t t){return std::ctime(&t);}static void listShow(const httplib::Request& rq, httplib::Response& rp){std::vector<BackupInfo> arry;_data->getAll(&arry);std::stringstream ss;ss << "<html><head><title>Download</title></head>";ss << " <body><h1>Download</h1><table>";for(auto& e : arry){ss << "<tr>";std::string filename = fileUtil(e.real_path).fileName();ss << "<td><a href='" << e.url << "'>" << filename << "</a></td>";ss << "<td align='right'>";ss << timeToString(e.modify_time);ss << "</td>";ss << "<td align='right'>";ss << e.file_size / 1024 << "K";ss << "</td>";ss << "</tr>";}ss << "</table></body></html>";rp.body = ss.str();rp.set_header("Content-Type", "text/html");rp.status = 200;}static std::string getETagInfo(const BackupInfo& info){std::string etag;etag += fileUtil(info.real_path).fileName();etag += "-";etag += std::to_string(info.file_size);etag += "-";etag += std::to_string(info.modify_time);return etag;}static void downLoad(const httplib::Request& rq, httplib::Response& rp){std::string url = rq.path;//std::cout << url << std::endl;BackupInfo info;_data->getBifoByUrl(url, &info);//std::cout << info.real_path << std::endl;if(info.pack_flag == true){//解压文件fileUtil fu(info.pack_path);fu.uncompress(info.real_path);//删除压缩文件, 并修改BackupInfo信息fu.Remove();info.pack_flag = false;_data->insert(info);}// if(rq.has_header("If-Range"))// std::cout << "hello" << std::endl;// else// std::cout << "no" << std::endl;// for(auto& e : rp.headers)// {// std::cout << e.second << std::endl;// }fileUtil fu(info.real_path);fu.getContent(&rp.body);rp.set_header("Accept-Ranges", "bytes");rp.set_header("ETag", getETagInfo(info));rp.set_header("Content-Type", "application/octet-stream");//rp.status = 200;if(rq.has_header("If-Range") && rq.get_header_value("If-Range") == getETagInfo(info)){rp.status = 206;//std::cout << rp.status << std::endl;}else{rp.status = 200;}}public:serevr(){Config* cnf = Config::getIstance();_server_port = cnf->getServerPort();_server_ip = cnf->getServerIp();_download_prefix = cnf->getDownloadPrefix();_back_dir = cnf->getBackDir();}bool RunModule(){_server.Post("/upload",upLoad);_server.Get("/listshow", listShow);_server.Get("/", listShow);std::string url = _download_prefix + "(.*)";_server.Get(url,downLoad);_server.listen("0.0.0.0", _server_port);return true;}private:int _server_port;std::string _server_ip;std::string _download_prefix;static std::string _back_dir;httplib::Server _server;};std::string serevr::_back_dir;
}
server.cc
#include "util.hpp"
#include "config.hpp"
#include "data.hpp"
#include "hot.hpp"
#include "server.hpp"
#include <thread>cloud::dataManager *_data;void server()
{cloud::serevr s;s.RunModule();
}
void hot()
{cloud::HotManager h;h.runMoudle();
}
int main(int argc, char *argv[])
{// if(argc != 2)// {// std::cout << argv[0] << " filepath newfilename" << std::endl;// exit(1);// }// std::string name = argv[1];// cloud::fileUtil f(name);// std::cout << f.fileSize() << std::endl;// std::cout << f.lastModifyTime() << std::endl;// std::cout << f.lastAccessTime() << std::endl;// std::cout << f.fileName() << std::endl;// std::string buffer;// f.getContent(&buffer);// name = argv[2];// cloud::fileUtil f2(name);// f2.setContent(buffer);// std::string name = argv[1];// cloud::fileUtil f(name);// f.compress(name += ".lz");// f.uncompress(name += ".backup");// cloud::fileUtil f(name);// f.createDirectory();// std::vector<std::string> arry;// f.getDirectory(&arry);// for(auto& e : arry)// {// std::cout << e << std::endl;// }// const char* name = "xiaolion";// int age = 18;// int score[] = {100, 98, 89};// Json::Value root;// root["name"] = name;// root["age"] = age;// root["socre"].append(score[0]);// root["socre"].append(score[1]);// root["socre"].append(score[2]);// std::string str;// cloud::JsonUtil::Serialize(root, &str);// std::cout << str << std::endl;// Json::Value val;// cloud::JsonUtil::UnSerialize(str, &val);// std::cout << val["name"].asString() << std::endl;// std::cout << val["age"].asInt() << std::endl;// std::cout << val["socre"][0].asInt() << std::endl;// std::cout << val["socre"][1].asInt() << std::endl;// std::cout << val["socre"][2].asInt() << std::endl;// cloud::Config* f = cloud::Config::getIstance();// std::cout << f->getHotTime() << std::endl;// std::cout << f->getServerPort() << std::endl;// std::cout << f->getServerIp() << std::endl;// std::cout << f->getDownloadPrefix() << std::endl;// std::cout << f->getPackfileSuffix() << std::endl;// std::cout << f->getPackDir() << std::endl;// std::cout << f->getBackDir() << std::endl;// std::cout << f->getBackupFile() << std::endl;// cloud::BackupInfo f;// f.NewBackupInfo(argv[1]);// cloud::fileUtil f1(argv[1]);// std::cout << f1.fileSize() << std::endl;// std::cout << argv[1] << std::endl;// std::cout << f.pack_flag << std::endl;// std::cout << f.file_size << std::endl;// std::cout << f.modify_time << std::endl;// std::cout << f.access_time << std::endl;// std::cout << f.real_path << std::endl;// std::cout << f.pack_path << std::endl;// std::cout << f.url << std::endl;// cloud::dataManager d;// d.insert(f);// f.pack_flag = true;// d.update(f);// cloud::BackupInfo tmp;// d.getBifoByRealPath(argv[1], &tmp);// std::cout << tmp.pack_flag << std::endl;// std::cout << tmp.file_size << std::endl;// std::cout << tmp.modify_time << std::endl;// std::cout << tmp.access_time << std::endl;// std::cout << tmp.real_path << std::endl;// std::cout << tmp.pack_path << std::endl;// std::cout << tmp.url << std::endl;// cloud::BackupInfo tmp2;// d.getBifoByUrl(f.url, &tmp2);// std::cout << tmp2.pack_flag << std::endl;// std::cout << tmp2.file_size << std::endl;// std::cout << tmp2.modify_time << std::endl;// std::cout << tmp2.access_time << std::endl;// std::cout << tmp2.real_path << std::endl;// std::cout << tmp2.pack_path << std::endl;// std::cout << tmp2.url << std::endl;// std::vector<cloud::BackupInfo> arry;// d.getAll(&arry);// for(auto& e : arry)// {// std::cout << e.pack_flag << std::endl;// std::cout << e.file_size << std::endl;// std::cout << e.modify_time << std::endl;// std::cout << e.access_time << std::endl;// std::cout << e.real_path << std::endl;// std::cout << e.pack_path << std::endl;// std::cout << e.url << std::endl;// }// cloud::BackupInfo f;// f.NewBackupInfo(argv[1]);// cloud::dataManager d;// d.insert(f);// cloud::dataManager d;// std::vector<cloud::BackupInfo> arry;// d.getAll(&arry);// for(auto& e : arry)// {// std::cout << e.pack_flag << std::endl;// std::cout << e.file_size << std::endl;// std::cout << e.modify_time << std::endl;// std::cout << e.access_time << std::endl;// std::cout << e.real_path << std::endl;// std::cout << e.pack_path << std::endl;// std::cout << e.url << std::endl;// }//_data = new cloud::dataManager();// cloud::HotManager ht;// ht.runMoudle();// cloud::serevr srv;// srv.RunModule();// httplib::Server _server;// _server.Post("/upload", upLoad);// _server.Get("/listshow", listShow);// _server.Get("/", listShow);// _server.Get("/", downLoad);// _server.listen("", 8080);_data = new cloud::dataManager();std::thread thread_hot(hot);std::thread thread_server(server);thread_hot.join();thread_server.join();return 0;
}
Makefile
.PHONY:util
cloudServer:cloudServer.ccg++ -o $@ $^ -L./lib -lpthread -lstdc++fs -ljsoncpp -lbundle
cloud.conf
{"hot_time" : 30,"server_port" : 8080,"server_ip" : "-.-.-.-","download_prefix" : "/download/","packfile_suffix" : ".lz","pack_dir" : "./packdir/","back_dir" : "./backdir/","backup_file" : "./cloud.dat"
}
相关文章:
【lesson8】云备份服务端完整版代码
文章目录 util.hppconfig.hpphot.hppdata.hppserver.hppserver.ccMakefilecloud.conf util.hpp #pragma once #include <iostream> #include <fstream> #include <string> #include <vector> #include <sys/stat.h> #include <unistd.h> …...

AI办公自动化:kimi批量搜索提取PDF文档中特定文本内容
工作任务:PDF文档中有资料来源这一行,比如: 资料来源:moomoo tech、The Information、Bloomberg、Reuters,浙商证券研究所 数据来源:CSDN、浙商证券研究所 数据来源:CSDN、arXiv、浙商证券研…...

基于C#开发web网页管理系统模板流程-总集篇
第一篇 基于C#开发web网页管理系统模板流程-登录界面和主界面_c#的网页编程-CSDN博客 第二篇 基于C#开发web网页管理系统模板流程-主界面管理员录入和编辑功能完善_c#网页设计-CSDN博客 第三篇 基于C#开发web网页管理系统模板流程-主界面管理员入库和出库功能完善_c#web程序设计…...

什么是DMZ?路由器上如何使用DMZ?
文章目录 📖 介绍 📖🏡 演示环境 🏡📒 DMZ 📒🚀 DMZ的应用场景💡 路由器设置DMZ🎈 注意事项 🎈⚓️ 相关链接 ⚓️📖 介绍 📖 在网络管理中,DMZ(Demilitarized Zone,隔离区)是一个特殊的网络区域,常用于将公共访问和内部网络隔离开来。DMZ功能允许…...
【bugfix】解决Redis缓存键清理问题
前言 在Spring Boot应用中集成Redis作为缓存存储时,合理配置RedisTemplate是确保数据正确存储和检索的关键。本文将通过对比分析一段初始存在问题的Redis配置代码及其修正后的版本,探讨如何正确处理Redis键前缀,以避免清理缓存时遇到的问题。…...

泛微开发修炼之旅--15后端开发连接外部数据源,实现在ecology系统中查询其他异构系统数据库得示例和源码
文章链接:15后端开发连接外部数据源,实现在ecology系统中查询其他异构系统数据库得示例和源码...

弹幕逆向signature、a_bogus
声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未经许可禁止转载&a…...
jEasyUI 使用标记创建树形菜单
jEasyUI 使用标记创建树形菜单 jEasyUI 是一个基于 jQuery 的用户界面插件库,它提供了一系列的组件,用于快速构建网页用户界面。其中,树形菜单(Tree Menu)是 jEasyUI 提供的一个非常实用的组件,它可以帮助…...
IT人的拖延——拖是因为不想离开“舒适区”?
人都是求“稳”的,在一个区域内呆了很久,也很舒适了,如果冒险离开进入未知的区域,万一结果不好怎么办?万一自己不适合怎么办?万一这个区域有着自己难以忍受的东西怎么办?这些对未知区域的恐惧感让我们在面对应该要做的事情时,不自觉地又拖延了起来。比如,我们在面临需…...

JUnit 5学习笔记
JUnit 5 学习笔记 1.JUnit5的改变2.JUnit5常用注解及测试2.1 DisplayName/Disabled/BeforeEach/AfterEach/BeforeAll/AfterAll2.2 Timeout2.3 RepeatedTest 3.断言3.1 简单断言3.2 数组断言3.3 组合断言3.4 异常断言3.5 超时断言3.6 快速失败 4.前置条件5.嵌套测试6.参数化测试…...

西格玛 ------ 第18个希腊字母学习
名词解释 在数学中,我们把∑作为求和符号使用,用小写字母σ,表示标准差。 ∑符号表示求和,读音为sigma,英文意思为Sum,Summation,汉语意思为“和”“总和”。 例1 公式使用说明:…...
【C语言】assert.h——断言
文章目录 主要内容调试和发布模式使用示例用法总结与注意事项 断言是一种用于在程序执行过程中进行调试的工具,能够帮助开发者验证程序的某些假设是否为真。如果断言失败,程序会终止,并输出一个错误消息,通常包含出错的文件名和行…...

HTML静态网页成品作业(HTML+CSS)—— 零食商城网页(1个页面)
🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有1个页面。 二、作品演示 三、代…...

虚函数机制-动态绑定的应用
虚函数使得程序在运行的时候根据指针指向对象的类型来确定调用哪个函数。 下图中:都为静态绑定。因为在编译器就确定了可以调用的函数 此时当基类指针指向派生类对象时,因为没有virtual关键字,所以在编译阶段就根据指针类型确定了要指向的函…...

MOS开关电路应用于降低静态功耗
本文主要讲述MOS开关电路的应用,过了好久突然想整理一下,有错误的地方请多多指出,在做电池类产品,需要控制产品的静态功耗,即使让芯片进入休眠状态,依旧功率很大,所以在电路中加一组软开关,防止…...

【每日刷题】Day65
【每日刷题】Day65 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. LCR 175. 计算二叉树的深度 - 力扣(LeetCode) 2. 序列找数_牛客题霸_牛客网…...

Oracle数据库连接并访问Microsoft SQL Server数据库
Oracle数据库连接并访问Microsoft SQL Server数据库 说明: 1.实际开发中,Oracle数据库与SQLServer数据库之间可能需要相互进行访问,方便业务数据抽取,编写视图及表等操作。 2.SQLServer访问Oracle数据库配置相对较为简单&…...
SQL 入门教程
SQL(Structured Query Language,结构化查询语言)是一种用于管理和操作关系数据库管理系统的编程语言。它被设计用来查询、更新、插入和删除数据库中的数据。SQL是一种标准化的语言,尽管在不同的数据库系统中可能存在一些差异&…...

Java—装饰器模式
介绍 装饰器模式 装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地将行为添加到现有的对象中,而无需修改其代码。装饰器模式提供了比继承更灵活的功能扩展方式。 主要角色 Component:定义一个对…...

服务器远程桌面经常连接不上,造成远程桌面连接不上的原因都有哪些
服务器远程桌面连接不稳定或经常连接不上是一个较为常见的技术问题,其可能的原因涉及多个层面,包括网络设置、服务器配置、系统安全等方面。下面将详细探讨一些可能造成远程桌面连接问题的主要原因: 首先,网络连接不稳定是导致远…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!
多连接 BLE 怎么设计服务不会乱?分层思维来救场! 作者按: 你是不是也遇到过 BLE 多连接时,调试现场像网吧“掉线风暴”? 温度传感器连上了,心率带丢了;一边 OTA 更新,一边通知卡壳。…...