我已经旋转了文件,并且需要定期更改文件,但是我无法更新指向文件的指针
var (
file *os.File
)
func init() {
file, err = os.Create(fileName)
}
func main() {
ticker = time.NewTicker(time.Second * 6)
defer ticker.Stop()
go func(file *os.File) {
<- ticker.C
fn := fmt.Sprintf("%d%s", time.Now().Unix(), ".txt")
file, _ = os.Create(fn)
}(file)
http.HandleFunc("/go", goHandler)
}
func goHandler(w http.ResponseWriter, r *http.Request) {
fmt.Printf("hand File: %v\n", *file)
// when handler triggered file stay the same
file.WriteString(myPayload)
}
它会在goroutines内部更改,但不会在处理程序中做出反应,因此文件始终保持不变。
建议,如何更改指向*os.File
的指针
答案 0 :(得分:3)
在您的代码中,goroutine仅运行一次。因此,它创建了一个新文件,仅执行一次操作-这意味着*file
仅更改了一次。
您应将<- ticker.C
更改为for _ = range ticker.C { ... }
。
而且,由于两个goroutine之间存在数据争用,因此您还应防止使用*file
来更改和读取sync.Mutex
中的值。
答案 1 :(得分:1)
或者,您可以在此for
循环中使用无限select
循环和for
语句(以防将来您还要处理其他通道上的其他信号,例如正常退出)。另外,您需要正确处理对指针的分配(需要将新值分配给指针的基础值)。您也可以删除将指针传递给goroutine的方法,而只是在goroutine之外修改全局指针,但是我不确定这是否是一个好习惯。
package main
import (
"fmt"
"log"
"net/http"
"os"
"sync"
"time"
)
var (
file *os.File
fnMutex sync.Mutex
err error
)
const fileName = "testFile"
func init() {
file, err = os.Create(fileName)
}
func main() {
ticker := time.NewTicker(time.Second * 6)
defer ticker.Stop()
go func(file *os.File) {
for {
select {
case <-ticker.C:
fn := fmt.Sprintf("%d%s", time.Now().Unix(), ".txt")
fnMutex.Lock()
newFile, _ := os.Create(fn)
*file = *newFile
fnMutex.Unlock()
}
}
}(file)
http.HandleFunc("/go", goHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func goHandler(w http.ResponseWriter, r *http.Request) {
fnMutex.Lock()
defer fnMutex.Unlock()
fmt.Printf("hand File: %v\n", *file)
// when handler triggered file stay the same
file.WriteString("test:" + time.Now().String() + "\n")
}