【问题标题】:Close the file before rename it in golang在golang中重命名之前关闭文件
【发布时间】:2018-12-05 17:22:53
【问题描述】:

当我使用 golang 进行一些文件操作时,我首先打开一个文件并将 close() 添加到延迟列表中,然后我尝试重命名该文件。如果我手动关闭文件,延迟将再次关闭它。如果我等待延迟关闭它,重命名将导致错误,因为它没有关闭是的。代码如下

func main() {

    pfile1, _ := os.Open("myfile.log")
    defer pfile1.Close() //It will be closed again.
    ...
    ...
    pfile1.Close() //I have to close it before rename it.
    os.Rename("myfile.log", "myfile1.log")
}

我找到了一些丑陋的解决方案,例如创建另一个函数来分离打开的文件,下面有没有更好的解决方案?

func main() {

    var pfile1 *os.File
    ugly_solution(pfile1)

    os.Rename("myfile.log", "myfile1.log")
}

func ugly_solution(file *os.File) {
    file, _ = os.Open("myfile.log")
defer file.Close()
}

【问题讨论】:

  • 为什么你还是把电话推迟到Close()?如果您必须调用它,您可以将延迟排除在外吗?

标签: go deferred


【解决方案1】:

您可以将关闭和重命名文件都放在 defer 中:

func main() { 
    pfile1, _ := os.Open("myfile.log")
    defer func(){
        pfile1.Close()
        os.Rename("myfile.log", "myfile1.log")   
    }() 
    ...
    ...
}

【讨论】:

  • 但是函数退出时会调用重命名,也许我想在重命名后添加更多代码。它不会灵活。
【解决方案2】:

我对您的代码有一些不清楚的地方。

首先,为什么要在重命名之前打开文件? os.Rename 函数不需要这样做。该函数接受两个字符串代表新旧文件名,不需要传递文件指针。

func main() {
    ...
    ...
    os.Rename("myfile.log", "myfile1.log")
}

假设您需要更改文件内容(考虑到ugly_solution 方法,情况似乎并非如此)并且您必须打开文件,那么为什么要推迟file.Close()?如果您需要在同一方法的某处显式调用该方法,则不必推迟该方法。简单地调用它。

func main() {
    pfile1, _ := os.Open("myfile.log")
    ...
    ...
    pfile1.Close()
    os.Rename("myfile.log", "myfile1.log")
}

【讨论】:

  • 是的,我想更改文件然后重命名它。作为建议,它不会将 Close() 添加到 defer 中。但是如果那样的话,Open() 和 Close() 之间会出现恐慌,那么 Close() 将不会被 defer 调用。
  • 然后将执行分成两部分。执行文件修改的部分,您打开/编辑/关闭的位置,以及您重命名的部分。不要将所有意图混合在一个方法中,
  • 感谢您的建议。拆分和不混合意图是一个好方法。
【解决方案3】:

在您的示例中的情况

也许你想遵循这个场景:

  • 轻松创建可识别的临时文件。
  • 写入数据。
  • 关闭文件。
  • 如果成功重命名文件。

在这种情况下,如果您想跟踪底层文件的操作系统系统操作,您可能只想不推迟关闭 IO.file,因为您想获得关闭函数本身返回的错误。

另外,在这种情况下,您可能也想操作 file.sync()。

https://www.joeshaw.org/dont-defer-close-on-writable-files/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-30
    • 2012-01-04
    • 2016-07-13
    • 1970-01-01
    • 2012-05-25
    • 2018-05-01
    • 1970-01-01
    • 2014-09-14
    相关资源
    最近更新 更多