更改指向* os.File的指针

时间:2018-07-06 14:52:29

标签: go

我已经旋转了文件,并且需要定期更改文件,但是我无法更新指向文件的指针

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的指针

2 个答案:

答案 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")
}