我在Python中有以下代码:
if not os.path.exists(src): sys.exit("Does not exist: %s" % src)
if os.path.exists(dst): sys.exit("Already exists: %s" % dst)
os.rename(src, dst)
Run Code Online (Sandbox Code Playgroud)
从这个问题,我知道没有直接的方法来测试文件是否存在或不存在.
在Go中编写上述内容的正确方法是什么,包括打印出正确的错误字符串?
这是我得到的最接近的:
package main
import "fmt"
import "os"
func main() {
src := "a"
dst := "b"
e := os.Rename(src, dst)
if e != nil {
fmt.Println(e.(*os.LinkError).Op)
fmt.Println(e.(*os.LinkError).Old)
fmt.Println(e.(*os.LinkError).New)
fmt.Println(e.(*os.LinkError).Err)
}
}
Run Code Online (Sandbox Code Playgroud)
从错误信息的可用性来看,如果没有你解析英文自由格式字符串,它实际上没有告诉你问题是什么,在我看来,不可能在Go中写出等价物.
您提供的代码包含竞争条件:在您检查dst不存在和复制内容之间dst,第三方可能已创建该文件dst,导致您覆盖文件.请删除os.path.exists(dst)检查,因为在尝试删除目标时无法可靠地检测目标是否存在,或者使用以下算法:
src到dst.如果dst存在名为的文件,则操作将失败,您可以挽救.如果src不存在,操作也将失败.src.以下代码实现了Go中概述的两步算法.
import "os"
func renameAndCheck(src, dst string) error {
err := os.Link(src, dst)
if err != nil {
return err
}
err = os.Remove(src)
if err != nil {
return err
}
}
Run Code Online (Sandbox Code Playgroud)
您可以检查调用os.Link()失败的原因:
os.IsNotExist(),则调用失败,因为src当时不存在os.Link()调用os.IsExist(),则调用失败,因为此时dst存在os.Link()调用os.IsPermission(),则调用失败,因为您没有足够的权限来创建硬链接据我所知,其他原因(如文件系统不支持硬链接或创建src并dst处于不同的文件系统)不能可移植性测试.