golang os.Create 导致“没有这样的文件或目录”错误

Posted

技术标签:

【中文标题】golang os.Create 导致“没有这样的文件或目录”错误【英文标题】:golang os.Create cause "no such file or directory" error 【发布时间】:2017-04-11 02:53:31 【问题描述】:

一定很简单,但我似乎无法弄清楚。我不断收到“没有这样的文件或目录”错误。以为 Create 函数是创建一个新文件?

package main

import (
    "log"
    "os"
)

func main() 
    f, err := os.Create("~/golang-server.log")
    defer f.Close()
    if err != nil 
        panic(err.Error())
    
    log.SetOutput(f)

【问题讨论】:

这通常意味着目标目录不存在。 【参考方案1】:

您不能使用~$HOME 之类的环境变量来指定文件路径,它们是字符串文字,表示实际路径。你得到的错误是因为它将~/golang-server.log视为当前目录的相对路径,并且当前目录中没有目录~

使用手动创建的子目录~,您的代码将成功:

 ~/test/ mkdir \~
 ~/test/ go run t.go
 ~/test/ ls \~
golang-server.log

因此需要将absolute pathrelative path 传递给os.Create

【讨论】:

【参考方案2】:

您可以使用os.ExpandEnv 处理“~”,这仅在 sh/bash 上下文中才有意义。

os.Create(os.ExpandEnv("$HOME/golang-server.log"))

在更复杂的情况下,您需要确保基目录存在,因为os.Create 不会处理它。

这就是os.Create("~/golang-server.log") 会失败的原因,因为基本目录不存在并且os.Create 不会自动为您创建它。你需要像这样自己做:

func EnsureBaseDir(fpath string) error 
    baseDir := path.Dir(fpath)
    info, err := os.Stat(baseDir)
    if err == nil && info.IsDir() 
       return nil
    
    return os.MkdirAll(baseDir, 0755)

注意:

$HOME 并不总是存在,例如该程序作为系统级别的systemd 服务运行。所以你最好不要在生产环境中使用$HOMEos.Create 的限制不仅仅存在于 Go 中。它是由操作系统内核引起的,广泛存在于其他语言/stdlib 中。

【讨论】:

以上是关于golang os.Create 导致“没有这样的文件或目录”错误的主要内容,如果未能解决你的问题,请参考以下文章

golang package log

golang写入csv

golang 日志输出到指定位置代码

golang 文件基本操作

golang之log rotate

golang导出csv乱码解决方法