Golang Go语言中如何在移动文件?
import (
"os"
)
func main(){
err := os.Rename("/home/go/v2ex/user.conf", “/home/go/v2ex/bak/userX.20240731”)
fmt.Println(err)
}
- /home/go/v2ex/userX.conf 为 文件
- /home/go/v2ex/userX.20240731 为备份目录
问题
- 同样的操作在 linux 下使用 mv 是正常如预期的操作(将文件移动到目录中)
- 同样的操作在 go 下是 error: file exists ,go 应该调用的是 c 的 rename
Golang Go语言中如何在移动文件?
更多关于Golang Go语言中如何在移动文件?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
首先, 其次, 然后你的代码改这个就可以了
err = os.Rename(“a.conf”, “a.bak/a.conf”)
更多关于Golang Go语言中如何在移动文件?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你理解 mv a.conf a.bak 和 mv a.conf a.bak/ 的区别, 就不会那样写代码了
可是无论 mv a.conf a.bak 和 mv a.conf a.bak/ 在 unix 下都是相同的表现啊? mv a.conf a.bak 就是把文件移动到目录中
mv 命令不单单是调用了 rename_at 这个 syscall ,还做了很多别的事情。比如跨 filesystem 的时候,rename_at 会失败,但是 mv 会复制过去再删掉原本的文件。
这个的确可以解决,用了这个方式,我就不需要用#替代.了
即使是 mv 这样看起来很简单的 command tool ,做的工作也比想象中得多,和 syscall 肯定不是一个粒度的,这个 case 里你用 strace 来跟踪下 mv 产生的 syscall 就知道了。
mv 先会尝试去直接 rename 到 dir 这个目录上,但是 syscall 报错 file exists
renameat2(AT_FDCWD, “test-file”, AT_FDCWD, “dir”, RENAME_NOREPLACE) = -1 EEXIST (File exists)
mv 应该特殊处理了这个错误,第二次会尝试 rename 到 dir/test-file
renameat2(AT_FDCWD, “test-file”, AT_FDCWD, “dir/test-file”, RENAME_NOREPLACE) = 0
如下语言内置库支持 move
https://docs.python.org/3/library/shutil.html
https://learn.microsoft.com/en-us/dotnet/api/system.io.file.move
https://docs.oracle.com/javase/tutorial/essential/io/move.html
如下语言不支持 move ,但是注释写的很明确
https://doc.rust-lang.org/std/fs/fn.rename.html
On Unix, if from is a directory, to must also be an (empty) directory. If from is not a directory, to must also be not a directory
这是 go 语言的注释
https://pkg.go.dev/os#Rename
Rename renames (moves) oldpath to newpath. If newpath already exists and is not a directory, Rename replaces it. OS-specific restrictions may apply when oldpath and newpath are in different directories. …
好像不需要了解太多原理……
单纯想告诉你,L:52 应该改为 err = os.Rename(“a.conf”, “a.bak/a.conf”)
在 Go 中,os.Rename() 函数是对 POSIX 标准中 rename() 系统调用的包装。虽然有些系统没有 rename()(比如 macOS ),但 os.Rename()仍然在尽力保持 rename() 包装的调用,为此会用一些当前系统支持的其他命令来达到。
所以它没办法单纯的被理解为 mv 指令。
在Golang中移动文件通常可以使用标准库中的os
包来实现,虽然os
包没有直接提供一个名为“移动文件”的函数,但可以通过重命名文件(如果源文件和目标文件位于同一文件系统)或使用组合操作(复制然后删除)来实现跨文件系统的文件移动。
方法一:使用os.Rename
(适用于同一文件系统)
如果源文件和目标文件在同一个文件系统中,可以使用os.Rename
函数直接重命名文件,这本质上就是移动文件。
package main
import (
"fmt"
"os"
)
func main() {
src := "source.txt"
dst := "destination.txt"
err := os.Rename(src, dst)
if err != nil {
fmt.Println("Error renaming file:", err)
} else {
fmt.Println("File moved successfully")
}
}
方法二:复制并删除(适用于跨文件系统)
如果源文件和目标文件在不同的文件系统中,需要先复制文件内容,然后删除源文件。这可以通过io/ioutil
包中的ioutil.ReadFile
和ioutil.WriteFile
函数,或者更高效地通过os
包的os.Open
和os.Create
结合io.Copy
来实现。
注意,无论哪种方法,都需要处理可能出现的错误,例如文件不存在、权限问题等。在实际开发中,根据需求选择合适的方法,并确保对错误进行适当的处理。