C++项目实战——基于多设计模式下的同步异步日志系统-⑤-实用工具类设计

文章目录

  • 专栏导读
  • 获取系统时间
    • time介绍
  • getTime函数设计
  • 判断文件是否存在
    • stat介绍
    • exists函数设计
  • 获取文件所在路径
    • find_last_of介绍
    • path函数设计
  • 创建文件所在目录
    • mkdir介绍
    • find_first_of介绍
    • 函数createDirectory设计
  • 实用工具类整理

专栏导读

🌸作者简介:花想云 ,在读本科生一枚,C/C++领域新星创作者,新星计划导师,阿里云专家博主,CSDN内容合伙人…致力于 C/C++、Linux 学习。

🌸专栏简介:本文收录于 C++项目——基于多设计模式下的同步与异步日志系统

🌸相关专栏推荐:C语言初阶系列C语言进阶系列C++系列数据结构与算法Linux

在这里插入图片描述
在项目中,我们时常会需要用到一些与业务无关的功能,如:获取系统时间、创建目录、获取路径等。我们将这些零碎的功能接口提前完成,以便于项目中会用到。

实用工具类主要包含以下功能:

  • 获取系统时间
  • 判断文件是否存在
  • 获取文件所在路径
  • 创建文件所在目录

获取系统时间

我们将获取系统时间的接口单独封装在一个Date类中。获取系统时间,我们可以使用库函数time来实现。

time介绍

C语言中的time函数是一个用于获取当前系统时间的标准库函数,它定义在<time.h>头文件中。time函数通常返回自1970年1月1日以来经过的秒数,这被称为Unix时间戳(或Epoch时间)。它的函数原型如下:

time_t time(time_t *tloc);
  • time_t是一种数据类型,通常是一个整数类型(如long),用来存储时间值;
  • tloc是一个指向time_t类型的指针,用于存储获取的时间值。你可以将它设置为NULL,如果你不需要获取时间值的副本;

time函数返回一个表示当前时间的时间戳,单位是。如果传递了非空的tloc指针,它还会将时间戳的副本存储在tloc指向的地址中,以便你可以稍后使用。

getTime函数设计

#include <iostream>
#include <ctime>class Date
{
public:static size_t getTime(){return (size_t)time(nullptr);}
};

判断文件是否存在

判断文件是否存在、获取文件所在路径、创建目录这三个功能都与文件相关,因此我们将三者在一个File类中实现。

实现思路:

  • 函数参数为一个路径字符串,表示所要判断的文件的路径;
  • 函数返回值为bool类型,若该文件存在则返回true
  • 通过系统调用stat来实现;

stat介绍

认识stat函数之前我们首先认识一下struct stat类型。

在C语言中,struct stat是一个用于表示文件或文件系统对象属性的结构体类型。这个结构体通常用于与文件和目录相关的操作,例如获取文件的大小、访问权限、最后修改时间等信息。struct stat类型的定义通常由操作系统提供,因此其具体字段可能会因操作系统而异。

以下是一个典型的struct stat结构体的字段,尽管具体字段可能会因操作系统而异:

struct stat {dev_t     st_dev;         // 文件所在设备的IDino_t     st_ino;         // 文件的inode号mode_t    st_mode;        // 文件的访问权限和类型nlink_t   st_nlink;       // 文件的硬链接数量uid_t     st_uid;         // 文件的所有者的用户IDgid_t     st_gid;         // 文件的所有者的组IDoff_t     st_size;        // 文件的大小(以字节为单位)time_t    st_atime;       // 文件的最后访问时间time_t    st_mtime;       // 文件的最后修改时间time_t    st_ctime;       // 文件的最后状态改变时间blksize_t st_blksize;     // 文件系统I/O操作的最佳块大小blkcnt_t  st_blocks;      // 文件占用的块数
};

struct stat结构体中的这些字段提供了关于文件或目录的各种信息。不同的操作系统可能会提供额外的字段,或者字段的意义可能会有所不同。

stat函数用于获取与指定路径名相关联的文件或目录的属性,并将这些属性填充到一个struct stat结构体中。以下是stat函数的函数原型:

int stat(const char *pathname, struct stat *statbuf);
  • pathname是要获取属性的文件或目录的路径名;
  • statbuf是一个指向struct stat结构体的指针,用于存储获取到的属性信息;
  • stat函数返回一个整数值,如果操作成功,返回0;如果出现错误,返回-1,并设置errno全局变量以指示错误的类型。

注意需要包含头文件<sys/stat.h><unistd.h>来使用stat函数。

exists函数设计

static bool exists(const std::string &pathname)
{struct stat st;if (stat(pathname.c_str(), &st) < 0) // 打开文件失败则代表文件不存在{return false;}return true;
}

获取文件所在路径

假设存在文件“user/aaa/bbb/ccc/test.cc”,我们需要获取文件test.cc所在的路径即"user/aaa/bbb/ccc"

实现这个功能我们将会用到库函数find_last_of

find_last_of介绍

C++标准库中的find_last_of函数是用于在字符串中查找指定字符集中最后一个出现的字符,并返回其位置或索引。这个函数通常用于字符串操作,允许你在字符串中查找某些字符集的最后一个匹配字符。

函数格式如下:

size_t find_last_of(const string& str, size_t pos = string::npos) const;
size_t find_last_of(const char* s, size_t pos = string::npos) const;
size_t find_last_of(const char* s, size_t pos, size_t n) const;

其中,

  • str是要搜索的字符串;
  • s是要查找的字符集;
  • pos是可选的参数,用于指定搜索的起始位置,默认为string::npos,表示从字符串的末尾开始向前搜索。

这个函数返回匹配字符集中任何字符的最后一个位置的索引,如果未找到匹配字符,则返回string::npos。需要注意的是,返回的索引是从0开始的。

path函数设计

就以文件“user/aaa/bbb/ccc/test.cc”为例,要想获取文件路径,我们只需要找到最后一个‘/ 或者 \\所在位置,并将在这之前的内容全部返回即可。若不存在路径分隔符/或者 \\,则证明该文件在当前目录,返回. 即可。

static std::string path(const std::string &pathname)
{size_t pos = pathname.find_last_of("/\\");if (pos == std::string::npos)return ".";return pathname.substr(0, pos + 1);
}

创建文件所在目录

以文件路径'' user/aaa/bbb/ccc/test.cc '',给函数传递该路径字符串,函数的任务是依次创建目录useraaabbbccc

需要注意的小细节是,每次要创建一个目录时,都要判断该目录是否存在,使用之前实现的exists函数即可。

我们依靠系统调用mkdir来完成目录的创建,首先来认识一下mkdir

mkdir介绍

mkdir 函数是一个系统调用,用于在文件系统中创建新的目录(文件夹)。它通常用于在文件系统中创建一个新的目录,以便存储文件或其他目录。

函数原型如下:

#include <sys/stat.h>
#include <sys/types.h>int mkdir(const char *pathname, mode_t mode);
  • pathname 是一个字符串,表示要创建的目录的路径。这个路径可以是相对路径绝对路径

  • mode 是一个权限掩码,用于指定新目录的权限。这个权限掩码通常是八进制数;

mkdir 函数的功能是创建一个新的目录,并根据指定的权限设置来设置目录的权限。如果成功创建目录,函数将返回0,否则返回-1,并设置 errno 变量以指示错误的原因。

find_first_of介绍

在 C++ 中,find_first_of 是字符串(std::string)和其他序列容器中的成员函数,用于在目标字符串中查找第一个匹配源字符串中任何字符的位置。它的功能是找到目标字符串中的任何一个字符在源字符串中第一次出现的位置。

函数类型如下:

size_t find_first_of(const std::basic_string& str, size_t pos = 0) const;
size_t find_first_of(const CharT* s, size_t pos = 0) const;
size_t find_first_of(const CharT* s, size_t pos, size_t n) const;
size_t find_first_of(CharT ch, size_t pos = 0) const;
  • str:一个字符串,表示源字符串,函数将在目标字符串中查找源字符串中的任何字符;
  • s:一个字符数组或 C 字符串,表示源字符序列,函数将在目标字符串中查找数组中的任何字符;
  • ch:一个字符,表示要查找的字符;
  • pos:可选参数,表示开始查找的位置。默认为0,即从字符串的开头开始查找;
  • n:可选参数,与 s 一起使用,表示要查找的字符数量;

find_first_of 函数返回目标字符串中第一个匹配源字符序列中任何字符的位置(索引),如果没有找到匹配的字符,则返回 std::string::npos

函数createDirectory设计

static void createDirectory(const std::string pathname)
{size_t pos = 0, idx = 0;while(idx < pathname.size()){pos = pathname.find_first_of("/\\", idx);if(pos == std::string::npos){mkdir(pathname.c_str(), 0777);}std::string parent_dir = pathname.substr(0, pos + 1);if(exists(parent_dir) == true) // 判断该文件是否已经存在{idx = pos + 1;continue;}mkdir(parent_dir.c_str(), 0777);idx = pos + 1;}
}

实用工具类整理

在项目实现中,我们最好使用自己的命名空间。我们将各个类整体放入LOG(名称自行决定)命名空间中的util命名空间中。

#ifndef __M_UTIL_H__
#define __M_UTIL_H__/* 使用工具类实现:1. 获取系统时间2. 判断文件是否存在3. 获取文件所在路径4. 创建文件所在目录
*/#include <iostream>
#include <ctime>
#include <sys/stat.h>namespace LOG
{namespace util{class Date{public:static size_t getTime(){return (size_t)time(nullptr);}};class File{public:static bool exists(const std::string &pathname){struct stat st;if (stat(pathname.c_str(), &st) < 0) // 打开文件失败则代表文件不存在{return false;}return true;}static std::string path(const std::string &pathname){size_t pos = pathname.find_last_of("/\\");if (pos == std::string::npos)return ".";return pathname.substr(0, pos + 1);}static void createDirectory(const std::string pathname){size_t pos = 0, idx = 0;while(idx < pathname.size()){pos = pathname.find_first_of("/\\", idx);if(pos == std::string::npos){mkdir(pathname.c_str(), 0777);}std::string parent_dir = pathname.substr(0, pos + 1); // 判断该文件是否已经存在if(exists(parent_dir) == true){idx = pos + 1;continue;}mkdir(parent_dir.c_str(), 0777);idx = pos + 1;}}};}
}
#endif

在这里插入图片描述

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

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

相关文章

Linux 修改SSH的显示样式,修改终端shell显示的样式,美观更改

要修改SSH的显示样式&#xff0c;您可以使用自定义的PS1&#xff08;提示字符串1&#xff09;变量来更改命令行提示符的外观。在您的情况下&#xff0c;您想要的格式似乎包括日期和时间&#xff0c;以及当前目录。以下是一个示例PS1设置&#xff0c;可以实现您所描述的样式&…

使用 Webpack 从 0 到 1 构建 Vue3 项目 + ts

使用 Webpack 从 0 到 1 构建 Vue3 项目 1.初始化项目结构2.安装 webpack&#xff0c;补充智能提示3.初步编写 webpack.config.js3.1设置入口文件及出口文件3.2 指定 html 模板位置 4.配置 运行/打包 命令&#xff0c;首次打包项目5.添加 Vue 及相关配置5.1安装并引入 vue5.2 补…

Vue3+移动端适配屏幕+默认横屏展示

效果图展示区: 1. 想要把px自动转换单位为vw需要项目根目录.postcssrc.js中进行配置以下代码 module.exports {plugins: {autoprefixer: {}, // 用来给不同的浏览器自动添加相应前缀&#xff0c;如-webkit-&#xff0c;-moz-等等"postcss-px-to-viewport": {unitTo…

【面试题】前端开发中如何高效渲染大数据量?

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 【国庆头像】- 国庆爱国 程序员头像&#xff01;总有一款适合你&#xff01; 在日常工作中&#xff0c;较少的能遇到一次性往页面中插入大量数据的场景…

易点易动固定资产管理系统:助力事业单位实现固定资产智能化管理

在日常运营中&#xff0c;事业单位面临着大量固定资产的管理挑战。为了提高资产利用率、降低运营成本&#xff0c;并确保资产安全与准确的账务管理&#xff0c;事业单位亟需一款强大而智能的固定资产管理系统。易点易动固定资产管理系统应运而生&#xff0c;为事业单位提供了一…

vue网页缓存页面与不缓存页面处理

在主路由页面 <template><div style"height: 100%"><!-- 缓存 --><keep-alive><router-view v-if"$route.meta.keepAlive"></router-view></keep-alive><!-- 不缓存 --><router-view v-if"!$rou…

ChatGPT 和 Elasticsearch:APM 工具、性能和成本分析

作者&#xff1a;LUCA WINTERGERST 在本博客中&#xff0c;我们将测试一个使用 OpenAI 的 Python 应用程序并分析其性能以及运行该应用程序的成本。 使用从应用程序收集的数据&#xff0c;我们还将展示如何将 LLMs 成到你的应用程序中。 在之前的博客文章中&#xff0c;我们构建…

Can‘t load the model for ‘stabilityai/sd-vae-ft-mse‘

Can’t load the model for ‘stabilityai/sd-vae-ft-mse’. If you were trying to load it from ‘https://huggingface.co/models’, make sure you don’t have a local directory with the same name. Otherwise, make sure ‘stabilityai/sd-vae-ft-mse’ is the correct…

iOS pod repo push 报错 ld: file not found: libarclite_iphoneos.a 问题解决方案

背景 Xcode 升级 14.3 之后&#xff0c;在Xcode 运行项目会收到以下错误 File not found: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a 项目中可以通过以下方法解决编译错误&#xff0c;就是在 …

铝及铝合金产品标识知识学习记录

声明 本文是学习GB-T 42916-2023 铝及铝合金产品标识. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1— 圆铸锭表面&#xff1b; 2——切完头尾的圆铸锭尾端(引锭头端)。 图 9 圆铸锭刻痕标识示意图(一) 示 例 2 : 5A06 牌号、铸态、尺寸规格为…

uniapp微信小程序《隐私保护协议》弹窗处理流程

背景 《关于小程序隐私保护指引设置的公告》 《小程序隐私协议开发指南》 流程 1.第一步 必须设置且审核通过&#xff01;&#xff01;&#xff01; 2.第二步 uniapp在manifest.json中添加&#xff01;&#xff01;&#xff01; /* 在 2023年9月15号之前&#xff0c;在 ap…

景联文科技可为多模态语音翻译模型提供数据采集支持

8月22日Facebook的母公司Meta Platforms发布了一种能够翻译和转录数十种语言的人工智能模型——SeamlessM4T&#xff0c;可以在日常生活中或者商务交流中为用户提供更便捷的翻译和转录服务。 相较于传统的文本翻译&#xff0c;这项技术的最大区别在于它可以实现端到端的语音翻译…

4.4-Spring源码循环依赖终极讲解

回顾上期内容 new 容器 new AnnotateBeanDefinitionReader 的时候创建很多创世纪的类&#xff0c;其中有一个ConfigurationPostProcessor是用来解析配置类的&#xff0c;将其注册起来存到Bean定义的Map中【这个类是基于Bean工厂后置处理器的】 这一步是将配置类注册到Bean定…

C++之编译时预定义宏flag(二百一十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

按图搜索淘宝商品(拍立淘)API接口 搜爆款商品 图片搜索功能api 调用示例

接口名称&#xff1a;item_search_img 公共参数 请求地址: 测试item_search_img 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_s…

Linux 下spi设备驱动

参考&#xff1a; Linux kernel 有关 spi 设备树参数解析 Linux kernel 有关 spi 设备树参数解析 - 走看看 Linux SPI驱动框架(1)——核心层 Linux SPI驱动框架(1)——核心层_linux spi驱动模型_绍兴小贵宁的博客-CSDN博客 Linux SPI驱动框架(2)——控制器驱动层 Linux SPI驱…

Redis过期时间的思考

当我们把 Redis 当做缓存来使用时&#xff0c;设置过期时间是必须的&#xff0c;但具体设置多少的过期时间呢&#xff0c;针对不同的场景会有不同的决策。 虚假一个场景&#xff0c;我们基于用户的地理位置推荐附近的陌生主播&#xff0c;用户可以线下去找主播沟通。当系统第一…

【PickerView案例08-国旗搭建界面加载数据 Objective-C预言】

一、来看我们第三个案例 1.来看我们第三个关于PickerView的一个案例, 首先呢,我要问大家一下, 咱们这个是几组数据呢, 这是一个pickerView,只不过,它显示的是什么,一个界面, 前面两个案例,都是文字 这个案例,开始有图片了, 总结一下这三个案例: 1)第一个案例…

R3LIVE源码解析(10) — R3LIVE中r3live_vio.cpp文件

目录 1 r3live_vio.cpp简介 2 r3live_vio.cpp源码解析 1 r3live_vio.cpp简介 R3LIVE主要的公式推导在VIO上&#xff0c;所以我们来细细的分析这部分的功能。R3LIVE将VIO分成了两步&#xff0c;一是直接通过帧间的光流来追踪地图点&#xff0c;并且通过最小化追踪到的地图点的…

C++之打印编译全过程(二百一十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…