当前位置: 首页 > wzjs >正文

郑州建设网站推广公司前端和网站开发的区别

郑州建设网站推广公司,前端和网站开发的区别,印刷公司网站模板,韩国设计交流网站C项目 —— 基于多设计模式下的同步&异步日志系统(2)(工厂模式) 基类实现滚动文件文件名问题 工厂模式一些扩展点struct tm 成员列表关键注意事项使用示例1. 获取当前时间并打印2. 与 strftime 配合使用3. 构造自定义时间 常见…

C++项目 —— 基于多设计模式下的同步&异步日志系统(2)(工厂模式)

  • 基类实现
  • 滚动文件
    • 文件名问题
  • 工厂模式
  • 一些扩展点
      • `struct tm` 成员列表
      • 关键注意事项
      • 使用示例
        • 1. 获取当前时间并打印
        • 2. 与 `strftime` 配合使用
        • 3. 构造自定义时间
      • 常见问题
      • 可视化记忆表

我们在之前把日志消息的主体已经组织好了,而且我们创建的适当的类控制日志格式,并且按照我们的格式组织日志消息。如果还没有看过的小伙伴可以点击这里:

https://blog.csdn.net/qq_67693066/article/details/147162921?sharetype=blogdetail&sharerId=147162921&sharerefer=PC&sharesource=qq_67693066&spm=1011.2480.3001.8118

我们这次的任务是要完成日志器中的一个小功能实现:日志输出的方向,我们日志输出的方向有:控制台固定文件滚动文件。这个模块的实现还会涉及到工厂模式的使用

基类实现

首先设计思想还是比较清晰的,设计一个基类,派生出三个不同的方向,我们先实现两个方向比较简单的:

namespace logs
{//基类实现class BaseSink{public:using ptr = std::shared_ptr<BaseSink>; BaseSink(){}virtual ~BaseSink() {}virtual void log(const char *data, size_t len) = 0; //要继承实现的接口};class StdoutSink : public BaseSink{public://将日志消息写到标准输出void log(const char *data, size_t len){std::cout.write(data, len);}};class FixFileSink : public BaseSink {public:FixFileSink(const std::string& pathname):_pathname(pathname){//1.创建文件所在路径logs::utils::File::createDiretory(logs::utils::File::path(_pathname));//2.创建文件并打开_ofs.open(_pathname,std::ios::binary | std::ios::app);assert(_ofs.is_open());}//将日志消息写到固定文件中void log(const char *data, size_t len){_ofs.write(data,len);assert(_ofs.good());}private:std::string _pathname; //创建文件时的文件路径std::ofstream _ofs; //流式文件操作};
}

我们也可以顺便测试一下:

#include"utils.hpp"
#include"level.hpp"
#include"message.hpp"
#include"fometter.hpp"
#include "sink.hpp"int main()
{// std::cout << logs::utils::File::path("./abc/def");// logs::utils::File::createDiretory("./abc/def");//std::cout <<logs::Loglevel::toString(logs::Loglevel::value::DEBUG);logs::logMsg msg(logs::Loglevel::value::DEBUG,"main.cc",53,"root","格式化功能测试....");logs::Formetter fmt("abc[%d{%H:%M:%S}][%c]%T%m%n");std::string str = fmt.format(msg);//标准输入测试size_t len = str.size();logs:: StdoutSink st;st.log(str.c_str(),len);//文件测试logs::FixFileSink fx("../test/test.txt");fx.log(str.c_str(),len);
}

滚动文件

滚动文件意思是,如果这个文件日志已经被写满了,会自动换到一个新的文件写日志,写满了的话又继续换。

文件名问题

既然会不停的创建文件,我们就不得不考虑一个问题,文件名。文件名是不能重复的,那么有没有一种方式,能保证我们的文件名是绝对不会重复的呢?有的,时间戳,时间只要在流逝,时间戳就会变。我们可以让时间戳作为我们文件名的一部分,这样就可以保证文件绝对不会重复了。

    class RollFileSink : public BaseSink{public:private:std::string createNewFile(){//1.获取当前时间戳time_t time = logs::utils::Date::get_time();struct tm lt;localtime_r(&time,&lt);std::stringstream filename;filename << _basename;filename << lt.tm_year + 1900;filename << lt.tm_mon + 1;filename << lt.tm_mday;filename << lt.tm_hour;filename << lt.tm_min;filename << lt.tm_sec;filename << "-";filename << _name_count++;filename << ".log";return filename.str();}// 基础文件名 + 扩展文件名(以时间生成)组成一个实际的当前输出文件名size_t _name_count;std::string _basename; //基础文件名std::ofstream _ofs; //流式文件size_t _max_size; //最大文件大小size_t _cur_size: //当前文件大小};
   class RollFileSink : public BaseSink{public:RollFileSink(const std::string& basename,size_t max_size):_basename(basename),_name_count(0),_max_size(max_size),_cur_size(0){std::string pathname = createNewFile();//1、创建文件的所在路径logs::utils::File::createDiretory(logs::utils::File::path(pathname));// 2.创建并打开日志文件_ofs.open(pathname, std::ios::binary | std::ios::app);assert(_ofs.is_open());}// 将日志消息写到固定文件中void log(const char *data, size_t len){if(_cur_size > _max_size){_ofs.close();std::string pathname = createNewFile();//1、创建文件的所在路径logs::utils::File::createDiretory(logs::utils::File::path(pathname));// 2.创建并打开日志文件_ofs.open(pathname, std::ios::binary | std::ios::app);assert(_ofs.is_open());}_ofs.write(data, len);assert(_ofs.good());_cur_size += len;}private:std::string createNewFile(){//1.获取当前时间戳time_t time = logs::utils::Date::get_time();struct tm lt;localtime_r(&time,&lt);std::stringstream filename;filename << _basename;filename << lt.tm_year + 1900;filename << lt.tm_mon + 1;filename << lt.tm_mday;filename << lt.tm_hour;filename << lt.tm_min;filename << lt.tm_sec;filename << "-";filename << _name_count++;filename << ".log";return filename.str();}// 基础文件名 + 扩展文件名(以时间生成)组成一个实际的当前输出文件名size_t _name_count;std::string _basename; //基础文件名std::ofstream _ofs; //流式文件size_t _max_size; //最大文件大小size_t _cur_size; //当前文件大小};

我们可以测试一下:

    logs::RollFileSink roll("../test/mytest",1024);size_t cur = 0;while(cur < 1024 * 2){roll.log(str.c_str(),len);cur+=len;}

在这里插入图片描述

工厂模式

代码定义了一个名为 SinkFactory 的工厂类,用于创建日志输出器(Sink)的智能指针实例。它使用了现代 C++ 的模板和可变参数特性,是一个非常灵活通用的工厂实现:

    class SinkFactory{public:template<typename SinkType,typename... Args>static BaseSink::ptr create(Args && ...args){return std::make_shared<SinkType>(std::forward<Args>(args)...);}};
    auto st1 = logs::SinkFactory::create<logs::StdoutSink>();st1->log(str.c_str(),len);

这样我们不用用户直接接触接口,而是通过工厂,这样更具灵活性。

一些扩展点

struct tm 是 C/C++ 标准库中用于表示日历时间的结构体,定义在 <ctime> 头文件中。以下是其成员变量及详细说明:


struct tm 成员列表

成员类型说明取值范围注意事项
tm_secint0-61 (通常 0-59)允许闰秒
tm_minint分钟0-59
tm_hourint小时(24小时制)0-23
tm_mdayint月中的第几天(Day of month)1-31
tm_monint月份(从0开始)0-11 (0=1月)使用时需 +1
tm_yearint年份(从1900开始)0+=1900年使用时需 +1900
tm_wdayint星期几(从0开始,0=周日)0-6 (0=周日)
tm_ydayint年中的第几天(从0开始)0-365
tm_isdstint夏令时标志:
正数=启用
0=禁用
负数=信息不可用
-1, 0, 1

关键注意事项

  1. 特殊计数规则

    • 月份tm_mon 从 0 开始(0=1月,11=12月),显示时需要 +1
    • 年份tm_year 是 1900 年起的偏移量,真实年份 = tm_year + 1900
    • 星期tm_wday 中 0 表示周日
  2. 夏令时处理

    if (timeinfo.tm_isdst > 0) {std::cout << "夏令时生效";
    }
    
  3. 有效范围扩展

    • tm_sec 允许 60-61 以兼容闰秒
    • 其他字段超出范围时,mktime() 会自动标准化

使用示例

1. 获取当前时间并打印
#include <ctime>
#include <iostream>int main() {time_t now = time(nullptr);struct tm timeinfo;localtime_r(&now, &timeinfo);  // 线程安全版本std::cout << "当前时间: " << 1900 + timeinfo.tm_year << "-" << 1 + timeinfo.tm_mon << "-"<< timeinfo.tm_mday << " "<< timeinfo.tm_hour << ":"<< timeinfo.tm_min << ":"<< timeinfo.tm_sec;
}
2. 与 strftime 配合使用
char buf[64];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &timeinfo);
std::cout << "格式化时间: " << buf;
3. 构造自定义时间
struct tm custom_time = {0};
custom_time.tm_year = 2023 - 1900;  // 2023年
custom_time.tm_mon = 6 - 1;         // 6月
custom_time.tm_mday = 15;           // 15日
time_t t = mktime(&custom_time);    // 转换为time_t

常见问题

  1. 为什么年份从1900开始?
    历史原因,早期系统用2位数存储年份,1900为基准年。

  2. 如何获取时区信息?
    通过 tm_gmtofftm_zone(非标准扩展,需检查平台支持):

    #ifdef __linux__
    std::cout << "UTC偏移: " << timeinfo.tm_gmtoff / 3600 << "小时";
    #endif
    
  3. 线程安全注意

    • 优先使用 localtime_r()(POSIX)或 localtime_s()(Windows)
    • 避免使用非线程安全的 localtime()

可视化记忆表

struct tm {int tm_sec;    // 秒 [0,61]int tm_min;    // 分 [0,59]int tm_hour;   // 时 [0,23]int tm_mday;   // 日 [1,31]int tm_mon;    // 月 [0,11] ← 注意+1int tm_year;   // 年-1900  ← 注意+1900int tm_wday;   // 周几 [0,6] (0=周日)int tm_yday;   // 年内天数 [0,365]int tm_isdst;  // 夏令时标志
};

掌握这些成员的含义和特性,可以高效处理各种时间操作需求。


文章转载自:

http://PuBMGE7U.dzpnL.cn
http://Ck6bubHh.dzpnL.cn
http://SwiQLY95.dzpnL.cn
http://luRwpv9x.dzpnL.cn
http://0NGJoE4n.dzpnL.cn
http://u6YANzFh.dzpnL.cn
http://yGgXihjh.dzpnL.cn
http://hO48jiQB.dzpnL.cn
http://9AhtNjGN.dzpnL.cn
http://xuJQZCKQ.dzpnL.cn
http://f4oAFNp8.dzpnL.cn
http://BMGpE106.dzpnL.cn
http://uhEtvgEk.dzpnL.cn
http://Ij78jaio.dzpnL.cn
http://o48zmn4f.dzpnL.cn
http://XsitIDHT.dzpnL.cn
http://eFEgeDif.dzpnL.cn
http://MwblZ53l.dzpnL.cn
http://QeZoD83T.dzpnL.cn
http://fs1jyoqi.dzpnL.cn
http://S7xVNQ2N.dzpnL.cn
http://LdqP9kEl.dzpnL.cn
http://gSXPRIIP.dzpnL.cn
http://EBnupRys.dzpnL.cn
http://CmyizIaD.dzpnL.cn
http://IdfMaVJP.dzpnL.cn
http://o1nmfKI5.dzpnL.cn
http://zENTwwXq.dzpnL.cn
http://A0rCuu78.dzpnL.cn
http://10QghHw1.dzpnL.cn
http://www.dtcms.com/wzjs/671823.html

相关文章:

  • 网站搭建dns有用吗制作一个网站数据库怎么做的
  • 做网站流量怎么赚钱吗威海网站定制
  • 较成功营销网站的例子南昌官网seo
  • 网站适合用angular做吗注册个人公司需要什么条件
  • 免费的黄冈网站有哪些平台?老铁外链
  • 衡阳网站建设公司电话时事新闻最新消息
  • 西部数码网站打不开韩国虚拟空间网站
  • 网站建设怎么打广告北京百度推广排名优化
  • 企业网站建设可行性分析 技能训练自学网页设计的网站
  • 贵州建设官方网站网站 国际化
  • 自适应网站建站网站功能介绍是什么
  • 自己如何创建一个网站精美图表网站推荐
  • 有哪些网站做电子元器件比较好专门做酒的网站
  • 网站icp备案是什么意思工作室暴利项目
  • 郴州网站建设网站网上注册公司需要多长时间
  • 江苏省建设工程网站做餐厅网站的需求分析
  • 公司网站公司简介宣传夸大受处罚网站底部版权信息字体颜色
  • 现今网站开发的主流框架外链seo推广
  • 绥化北京网站建设微商网络推广怎么做
  • 通辽大柒网站建设有限公司华为弹性云做网站
  • 贪玩原始传奇官方网站网站建设跟版网
  • 网站开发技术有包括简易做网站的软件
  • 商品网站源码wordpress主题 网络公司
  • 百度软件下载中心官方网站苏州正规网站建设概况
  • .net 电子商务网站源码在线单页网站制作
  • 邯郸集团网站建设魔客吧wordpress主题安装
  • 怎样建设自己网站的后台wordpress敏感词
  • 怎么做网络乞丐网站制作可以赚钱的网站
  • 十堰微网站建设价格简述网站建设流程
  • 天津企业网站做推广可以上那些网站