我有很多记录器在我的应用程序中写入不同的文件。我正在尝试添加在应用程序运行时截断该文件的功能。这就是我所拥有的:
type Resource struct {
Logger *ResourceLogger
// other stuff pertaining to my resource...
}
func (r *Resource) SetLogger(logPath string) {
path := logPath + r.Name + ".log"
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("Unable to open log file '%v'", path)
}
r.Logger = &ResourceLogger{log.New(f, "", log.Ldate|log.Ltime), f}
}
type ResourceLogger struct {
*log.Logger
LogFile *os.File
}
这使我可以轻松地记录每个资源一个文件。但是,当我尝试使用Resource.Logger.LogFile.Truncate(0)时,我收到拒绝访问错误。
答案 0 :(得分:1)
我认为你在Windows上工作,因为Windows有像这样的锁定文件的习惯。我建议,既然你基本上可以控制日志写入和截断,你可以暂时关闭文件,然后在没有打开文件句柄的情况下截断它。
您必须使用例如互斥锁来阻止任何人在您截断时尝试记录任何内容,并在完成后重新打开日志文件以进行写入。这是一个粗略的例子:
package main
import (
"log"
"os"
"sync"
)
type Resource struct {
Logger *ResourceLogger
// other stuff pertaining to my resource...
Name string
}
func (r *Resource) SetLogger(logPath string) {
path := logPath + r.Name + ".log"
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("Unable to open log file '%v'", path)
}
r.Logger = &ResourceLogger{log.New(f, "", log.Ldate|log.Ltime), f, path, sync.Mutex{}}
}
func (r *ResourceLogger) Truncate() {
if r.logger != nil {
r.logmutex.Lock()
r.logfile.Close()
os.Truncate(r.logfilename, 0) // The file must not be open on Windows!
f, err := os.OpenFile(r.logfilename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("Unable to open log file '%v'", r.logfilename)
}
r.logger = log.New(f, "", log.Ldate|log.Ltime)
r.logfile = f
r.logmutex.Unlock()
}
}
type ResourceLogger struct {
logger *log.Logger
logfile *os.File
logfilename string
logmutex sync.Mutex
}
func (r *ResourceLogger) Println(s string) {
r.logmutex.Lock()
r.logger.Println(s)
r.logmutex.Unlock()
}
func main() {
r := Resource{}
r.Name = "jeejee"
r.SetLogger("")
r.Logger.Println("test one")
for {
r.Logger.Println("more logging")
r.Logger.Truncate()
}
}