golang File.Seek和File.Truncate

场景

在实际业务中这样一个需求,部署在某台机器上的程序,维护有一个id,这个id在程序内部每次收到请求时会 + 1,当程序崩溃重启时需要知道重启前的这个id值,这样当重启时就知道id应该取什么初始值了。这很明显是一个读少写多的场景。想到的方法有两种,一个是利用redis进行缓存,因为只需要维护一个id,并不需要很大的内存;一个是本地缓存,一个是按照文件进行维护,一个是按照共享内存维护。
起初使用了redis维护,想着方便。但是在测试中发现,会出现一些dail timeout的情况,想着并不稳妥,所以决定本地维护一个文件,在程序重启时open文件,在程序退出前close,类似于写日志一样。

因为文件里其实只是一个数字,所以在读的时候需要seek一下,在写的时候需要seek后truncate一下

Seek
func (f *File) Seek(offset int64, whence int) (ret int64, err error)

官方注释:Seek设置下一次读/写的位置。offset为相对偏移量,而whence决定相对位置:0为相对文件开头,1为相对当前位置,2为相对文件结尾。它返回新的偏移量(相对开头)和可能的错误。

Truncate
func (f *File) Truncate(size int64) error

官方注释:Truncate改变文件的大小,对文件进行截断,它不会改变I/O的当前位置。 如果截断文件,多出的部分就会被丢弃。如果出错,错误底层类型是*PathError。

实现

// 读
func Get() (string, error) {
	// 读需要从头开始,所以设置距离文件头0字节
	// Seek是设置下一次读写的位置
	F.Seek(0, 0)
	id, err := ioutil.ReadAll(F)
	if err != nil {
		return "", err
	}
	// 避免末尾是一个'\n'
	if id[len(id)-1] == '\n' {
		return string(id[:len(id)-1]), nil
	}
	return string(id), nil
}

// 写
func Set(id string) error {
	// 写需要从头开始写并覆盖
	F.Seek(0, 0)
	F.Truncate(0)
	_, err := F.Write([]byte(id))
	return err
}

本地共享内存的demo以后再更

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值