英文:
golang File WriteString cover
问题
我想通过文件获取递增的ID,以下是代码:
// 获取递增的ID
func GetID() uint64 {
appIdLock.Lock()
defer appIdLock.Unlock()
f, err := os.OpenFile(idPath, os.O_RDWR, 0666)
if err != nil {
return 0
}
defer f.Close()
// 读取
bufferTemp := make([]byte, 16)
bufferResult := make([]byte, 0)
for {
n, _ := f.Read(bufferTemp)
if n > 0 {
bufferResult = append(bufferResult, bufferTemp[:n]...)
} else {
break
}
}
if len(bufferResult) == 0 {
return 0
}
s := common.StringToUint64(string(bufferResult))
s += 1
// 写入(如何覆盖?)
f.Truncate(0)
f.Seek(0, 0)
f.WriteString(strconv.FormatUint(s, 10))
return s
}
f.WriteString
函数是追加写入的,例如,我的文件内容是 123
,运行 GetID()
后,我希望文件内容变为 124
,但实际结果是 123124
。为了覆盖写入,你可以使用 f.Truncate(0)
将文件截断为0字节,然后使用 f.Seek(0, 0)
将文件指针移动到文件开头,再进行写入操作。
英文:
I want get increment id with file, code as below:
// get increment id
func GetID() uint64 {
appIdLock.Lock()
defer appIdLock.Unlock()
f, err := os.OpenFile(idPath, os.O_RDWR, 0666)
if err != nil {
return 0
}
defer f.Close()
// Read
bufferTemp := make([]byte, 16)
bufferResult := make([]byte, 0)
for {
n, _ := f.Read(bufferTemp)
if n > 0 {
bufferResult = append(bufferResult, bufferTemp[:n]...)
} else {
break
}
}
if len(bufferResult) == 0 {
return 0
}
s := common.StringToUint64(string(bufferResult))
s += 1
// Write (how to cover?)
f.WriteString(strconv.FormatUint(s, 10))
return s
}
f.WriteString function was append, example, my file content: 123, run GetID() I hope my file content is: 124, But result was: 123124
答案1
得分: 1
不改变你的代码太多,这是一个可以工作并实现你想要的功能的解决方案。没有循环或多个字节切片。
func GetID() uint64 {
appIdLock.Lock()
defer appIdLock.Unlock()
// 添加 os.O_CREATE 以在文件不存在时创建文件。
f, err := os.OpenFile(idPath, os.O_RDWR+os.O_CREATE, 0666)
if err != nil {
fmt.Println(err)
return 0
}
defer f.Close()
// 预先知道文件内容,因此我分配了一个合适的字节切片。
fileStat, err := f.Stat()
if err != nil {
fmt.Println(err)
return 0
}
buffer := make([]byte, fileStat.Size())
_, err = f.Read(buffer)
if err != nil {
fmt.Println(err)
return 0
}
s, _ := strconv.ParseUint(string(buffer), 10, 64)
s += 1
// 这里的魔法在于~将字节写入文件的索引0处。
_, err = f.WriteAt([]byte(strconv.FormatUint(s, 10)), 0)
if err != nil {
fmt.Println(err)
return 0
}
return s
}
希望能对你有所帮助!
英文:
Without changing much of your code, here is the solution that will work and do what you want to do. No loops
or more than a single byte slice.
func GetID() uint64 {
appIdLock.Lock()
defer appIdLock.Unlock()
// Added + os.O_CREATE to create the file if it doesn't exist.
f, err := os.OpenFile(idPath, os.O_RDWR + os.O_CREATE, 0666)
if err != nil {
fmt.Println(err)
return 0
}
defer f.Close()
// Know file content beforehand so I allocate a suitable bytes slice.
fileStat, err := f.Stat()
if err != nil {
fmt.Println(err)
return 0
}
buffer := make([]byte, fileStat.Size())
_, err = f.Read(buffer)
if err != nil {
fmt.Println(err)
return 0
}
s, _ := strconv.ParseUint(string(buffer), 10, 64)
s += 1
// The Magic is here ~ Writes bytes at 0 index of the file.
_, err = f.WriteAt([]byte(strconv.FormatUint(s, 10)), 0)
if err != nil {
fmt.Println(err)
return 0
}
return s
}
<br />
Hope it helps!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论