1. // Copyright (c) 2024 LiuShuKu
  2. // Project Name : balance
  3. // Author : liushuku@yeah.net
  4. package cache
  5. import (
  6. "encoding/json"
  7. "log"
  8. "os"
  9. "strconv"
  10. "sync"
  11. )
  12. // Cache 结构体定义
  13. type Cache struct {
  14. data map[string]string
  15. mutex sync.RWMutex
  16. file string
  17. dirtyFlag bool // 标记数据是否已更改
  18. }
  19. // NewCache 创建新的 Cache 实例
  20. func NewCache(file string) *Cache {
  21. cache := &Cache{
  22. data: make(map[string]string),
  23. file: file,
  24. }
  25. if err := cache.load(); err != nil {
  26. log.Printf("加载缓存时出错: %v", err)
  27. }
  28. return cache
  29. }
  30. // Get 从缓存中获取值
  31. func (c *Cache) Get(key string) string {
  32. c.mutex.RLock()
  33. defer c.mutex.RUnlock()
  34. value, _ := c.data[key]
  35. return value
  36. }
  37. // Increment 自增接口
  38. func (c *Cache) Increment(key string) {
  39. c.mutex.Lock()
  40. defer c.mutex.Unlock()
  41. currentValue, found := c.data[key]
  42. var newValue int
  43. if found {
  44. currentInt, err := strconv.Atoi(currentValue)
  45. if err != nil {
  46. newValue = 1
  47. } else {
  48. newValue = currentInt + 1
  49. }
  50. } else {
  51. newValue = 1
  52. }
  53. c.data[key] = strconv.Itoa(newValue)
  54. c.dirtyFlag = true // 标记数据已更改
  55. c.saveIfDirty()
  56. }
  57. // Set 将值存入缓存
  58. func (c *Cache) Set(key, value string) {
  59. c.mutex.Lock()
  60. defer c.mutex.Unlock()
  61. if c.data[key] != value {
  62. c.data[key] = value
  63. c.dirtyFlag = true // 标记数据已更改
  64. }
  65. c.saveIfDirty()
  66. }
  67. // Save 持久化缓存到文件
  68. func (c *Cache) save() error {
  69. fileData, err := json.MarshalIndent(c.data, "", " ")
  70. if err != nil {
  71. log.Printf("序列化数据时出错: %v", err)
  72. return err
  73. }
  74. if err := os.WriteFile(c.file, fileData, 0644); err != nil {
  75. log.Printf("写入文件时出错: %v", err)
  76. return err
  77. }
  78. return nil
  79. }
  80. // Load 从文件加载缓存
  81. func (c *Cache) load() error {
  82. fileData, err := os.ReadFile(c.file)
  83. if err != nil {
  84. if !os.IsNotExist(err) {
  85. log.Printf("读取文件时出错: %v", err)
  86. }
  87. return err
  88. }
  89. if err := json.Unmarshal(fileData, &c.data); err != nil {
  90. log.Printf("解析 JSON 时出错: %v", err)
  91. return err
  92. }
  93. return nil
  94. }
  95. // saveIfDirty 如果数据已更改,则保存到文件
  96. func (c *Cache) saveIfDirty() {
  97. if c.dirtyFlag {
  98. if err := c.save(); err == nil {
  99. c.dirtyFlag = false // 保存成功后重置脏标记
  100. }
  101. }
  102. }

Golang 实现本地持久化缓存的更多相关文章

  1. iOS应用架构谈 本地持久化方案及动态部署

    转载: iOS应用架构谈 本地持久化方案及动态部署 前言 嗯,你们要的大招.跟着这篇文章一起也发布了CTPersistance和CTJSBridge这两个库,希望大家在实际使用的时候如果遇到问题,就给 ...

  2. ssiOS应用架构谈 本地持久化方案及动态部署

    本文转载至 http://casatwy.com/iosying-yong-jia-gou-tan-ben-di-chi-jiu-hua-fang-an-ji-dong-tai-bu-shu.html ...

  3. 微信小程序开发:学习笔记[9]——本地数据缓存

    微信小程序开发:学习笔记[9]——本地数据缓存 快速开始 说明 本地数据缓存是小程序存储在当前设备上硬盘上的数据,本地数据缓存有非常多的用途,我们可以利用本地数据缓存来存储用户在小程序上产生的操作,在 ...

  4. 四、NOSQL之Redis持久化缓存服务基础实战第三部

    1.NOSQL的理解 NOSQL是不仅仅是SQL,说的就是sql的补充,但是不能替代SQL. nosql库:memcached.memcachedb.redis 2.redis 简介 Redis是一个 ...

  5. IOS开发-本地持久化存储sqlite应用

    前言 需求描述 开发测试环境 FMDB介绍 创建工程 一.前言 上一章介绍了如何开发一个IOS应用的入门案例教程:                     我的第一个IOS开发应用    本章主要将介 ...

  6. iOS - LocalCache 本地数据缓存

    1.自定义方式本地数据缓存 1.1 自定义缓存 1 沙盒路径下的 Library/Caches 用来存放缓存文件,保存从网络下载的请求数据,后续仍然需要继续使用的文件,例如网络下载的离线数据,图片,视 ...

  7. Android清除本地数据缓存代码案例

    Android清除本地数据缓存代码案例 直接上代码: /*  * 文 件 名:  DataCleanManager.java  * 描    述:  主要功能有清除内/外缓存,清除数据库,清除shar ...

  8. Unity本地持久化类Playerprefs使用详解

    一.PlayerPrefs是什么? PlayerPrefs是Unity3d提供了一个用于数据本地持久化保存与读取的类.工作原理十分简单,就是以key-value的形式将数据保存在本地,然后在代码中可以 ...

  9. 如何清除本地DNS缓存 windows

    在您的网站迁移服务器时需要对域名所指向的IP进行更改,这时候在本机访问网站时就需要清除本地的DNS缓存信息,那么怎样清除呢? 首先我们应该明白清除DNS缓存信息的原理:当计算机对域名访问时并不是每次访 ...

  10. 刷新本地DNS缓存的方法

    http://www.cnblogs.com/rubylouvre/archive/2012/08/31/2665859.html 常有人问到域名解析了不是即时生效的嘛,怎么还是原来的呢?答案就是在本 ...

随机推荐

  1. 编译器-FIRST集合(补充:左递归)

    上一篇中实现的First函数没有考虑左递归,在这对此说明和实现 1.立即左递归 A -> Ab|a 1.两步或两步以上产生的左递归 A -> Bc|a B -> Ab|d 前面的实现 ...

  2. Docker安装开源版obs对象存储服务minio,并后台运行

    ​​>Minio 是一个基于Apache License v2.0开源协议的对象存储服务,虽然轻量,却拥有着不错的性能.它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据. 例如 ...

  3. k8s pod错误的排查步骤和处理方法

    查pod kubectl get pod -n amadeus -o wide 查pod日志 kubectl logs -f --timestamps -n amadeus weyo-server-6 ...

  4. 鼠标事件:mouseout、mouseover事件会不断触发

    mouseover 和 mouseenter mouseenter不会冒泡,而mouseover会冒泡 mouseover:指针进入事件监听的元素内 或者 其他的子元素内 都会触发mouseover ...

  5. 【WEB前端】【报错解决】This request has been blocked; the content must be served over HTTPS.

    问题描述 部署WEB项目后,开启了强制HTTPS,产生如下错误: Mixed Content: The page at 'https://ask.mllt.vip/index.php/data1.ht ...

  6. 创建LVM报错:Can't initialize physical volume "/dev/sdb1" of volume group "myvg" without -ff

    问题: 在使用fdisk /dev/sdb 删除原有LVM分区,在接着创建LVM新分区/dev/sdb1.完毕保存之后. 执行pvcreate /dev/sdb1出现报错 Can't initiali ...

  7. 波折重重:Linux实时系统Xenomai宕机问题的深度定位

    目录 一 前言 二 背景 三 原因分析及措施 硬件原因 应用软件 操作系统 四 分析定位 转机 拨云见雾 irq计数 Schedstat coreclk 现象结论 五 原因一 六 原因二 七 解决 八 ...

  8. Qt编写物联网管理平台40-类型种类

    一.前言 为了增强本系统的拓展性,做成通用的物联网管理平台,特意将控制器主设备类型.探测器子设备类型.对应种类符号等信息,全部做成表格可自定义添加和修改,这样在控制器信息表和探测器信息表管理的时候,可 ...

  9. Qt数据库应用12-通用数据库清理

    一.前言 很多项目如果需要存储很多日志记录比如运行日志,时间长了记录数量非常多,数据库体积不断增大,对应数据库表的增删改查的效率不断降低,为了消除这几个影响,需要有一套机制,不断将早期的数据清理,清理 ...

  10. vue3项目中报错:Unexpected mutation of "xxx" prop

    vue3 中element 弹窗绑定需要通过v-model,这个时候父级会传个dialogVisible(boolean值)过来,结果会报eslint的错. Unexpected mutation o ...