0 Star 0 Fork 0

shallot/Go开发工具集

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
list.go 2.68 KB
一键复制 编辑 原始数据 按行查看 历史
shallot 提交于 2024-06-06 22:48 . 添加filedb文件模拟数据库。
/*
* 大量同类数据,每一条对应一个文件。
* 多用于记录数量频繁变动、单条记录不可变的数据。
* 例如用于重试的失败网络请求等。
*/
package filedb
import (
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"sync"
)
type List[T any] struct {
Dirpath string // 文件目录
Prefix string // 文件前缀,和每一条数据ID直接拼接
Perm os.FileMode // 文件权限,默认0644
BatchCount int // 读取文件列表时批量数量,默认为1000
lock sync.RWMutex // 读写锁
}
// 新建一个文件存储
func NewList[T any](dirpath string, prefix string) *List[T] {
t := new(List[T])
t.Dirpath = dirpath
t.Prefix = prefix
t.Perm = 0644
t.BatchCount = 1000
t.lock = sync.RWMutex{}
return t
}
// 读取ID列表,不包含Prefix
func (t *List[T]) GetAllId() (idList []string, err error) {
t.lock.RLock()
defer t.lock.RUnlock()
dirFile, err := os.Open(t.Dirpath)
if err != nil {
return
}
defer dirFile.Close()
for {
files, e := dirFile.Readdir(t.BatchCount)
if e != nil {
if e != io.EOF {
err = e
}
return
}
for _, item := range files {
filename := item.Name()
if strings.HasPrefix(filename, t.Prefix) {
idList = append(idList, filename[len(t.Prefix):])
}
}
}
}
// 读取单个数据内容
func (t *List[T]) GetItem(dataId string) (data T, err error) {
t.lock.RLock()
defer t.lock.RUnlock()
fp := t.fullFilepath(dataId)
content, err := os.ReadFile(fp)
if err != nil {
return
}
if err = json.Unmarshal(content, &data); err != nil {
return
}
return
}
// 写入新的数据内容
func (t *List[T]) AddItem(dataId string, data T) (err error) {
_, isExist, err := t.IsExist(dataId)
if err != nil {
return
}
if isExist {
err = fmt.Errorf("数据%s已存在", dataId)
return
}
t.lock.Lock()
defer t.lock.Unlock()
content, err := json.Marshal(data)
if err != nil {
return
}
fp := t.fullFilepath(dataId)
if err = os.WriteFile(fp, content, t.Perm); err != nil {
return
}
return
}
// 删除数据内容
func (t *List[T]) RemoveItem(dataId string) (err error) {
t.lock.Lock()
defer t.lock.Unlock()
fp := t.fullFilepath(dataId)
if err = os.RemoveAll(fp); err != nil {
return
}
return
}
// 判断数据ID是否已经存在
func (t *List[T]) IsExist(dataId string) (isFile bool, isExist bool, err error) {
fp := t.fullFilepath(dataId)
info, e := os.Stat(fp)
if e != nil {
if os.IsNotExist(e) {
isExist = false
} else {
err = e
}
return
}
isExist = true
isFile = !info.IsDir()
return
}
// 文件路径拼接
func (t *List[T]) fullFilepath(dataId string) string {
return filepath.Join(t.Dirpath, t.Prefix+dataId)
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/gxsshallot/gotool.git
git@gitee.com:gxsshallot/gotool.git
gxsshallot
gotool
Go开发工具集
685317554a98

搜索帮助