草庐IT

go - 截断打开的 os.File(拒绝访问)

coder 2023-07-01 原文

我有很多记录器写入我的应用程序中的不同文件。我正在尝试添加在应用程序运行时截断该文件的功能。这是我的:

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) 时,出现拒绝访问错误。

最佳答案

我认为您是在 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()
    }
}

关于go - 截断打开的 os.File(拒绝访问),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25534857/

有关go - 截断打开的 os.File(拒绝访问)的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby-on-rails - rails : save file from URL and save it to Amazon S3 - 2

    从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex

  5. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  6. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  7. ruby CSV : How can I read a tab-delimited file? - 2

    CSV.open(name,"r").eachdo|row|putsrowend我得到以下错误:CSV::MalformedCSVErrorUnquotedfieldsdonotallow\ror\n文件名是一个.txt制表符分隔文件。我是专门做的。我有一个.csv文件,我转到excel,并将文件保存为.txt制表符分隔的文件。所以它是制表符分隔的。CSV.open不应该能够读取制表符分隔的文件吗? 最佳答案 尝试像这样指定字段分隔符:CSV.open("name","r",{:col_sep=>"\t"}).eachdo|row|

  8. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  9. ruby-on-rails - 如何在 mac os snow leopard 中升级 ruby​​ 和 rails - 2

    我想将我的MacSnowLeopardruby​​从1.8.7升级到1.9.1版本,有人知道轻松且最好的升级方法吗?因为我读了一些论坛/帖子/博客/讨论说覆盖苹果发布的ruby不好将Rails从版本2.2.2升级到2.3.8的最佳方法是什么?因为我找到的所有信息都仅适用于豹/老虎,而且很少有关于雪豹的复杂文章。他们还说覆盖apple提供的rails不好吗。谁能帮帮我?谢谢。 最佳答案 DanBenjamin有一些greatinstructionsforcompilingandinstallingRuby,RubyGemsandRai

  10. ruby - rbenv 安装权限被拒绝 - 2

    大家好,我正在尝试设置一个开发环境,并且我一直在关注以下教程:Linktotutorial我做得不是很好,除了最基本的版本控制内容外,我对终端命令没有任何实际经验。我点击了第一个链接并尝试运行source~/.bash_profile我得到了错误;mkdir:/usr/local/rbenv/shims:权限被拒绝mkdir:/usr/local/rbenv/versions:权限被拒绝现在每次我加载终端时都会出现错误。bash_profile的内容;exportPATH=/usr/local/rbenv/bin:$PATHexportRBENV_ROOT=/usr/local/rbe

随机推荐