Golang 1.22.2
在项目涉及到了一个功能点,就是文件的移动,最开始是在windows下使用,然后发布到linux,业务第一阶段文件是一个分区下,代码还能正常运行,后期文件太多,一个分区装不下了,这时扩容了一个新的分区,然后就出现了*LinkError.
错误,看到源码才知道,在非Unix
系统下即使在同一个目录,Rename 不是原子操作。
,源代码说明如下:
go// 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.
// Even within the same directory, on non-Unix platforms Rename is not an atomic operation.
// If there is an error, it will be of type *LinkError.
func Rename(oldpath, newpath string) error {
return rename(oldpath, newpath)
}
不能使用这个方法来移动文件后,还有其他方式吗,目前处理的方案是先复制,然后再删除,实际使用下来的效率是低于最开始使用的Rename
。
实例代码如下:
gofunc MoveFile(srcDir, destDir, move string) {
files, err := os.ReadDir(srcDir)
if err != nil {
return
}
for _, file := range files {
fileName := file.Name()
// 判断文件是否存在,如果存在则删除,否则则移动对应的文件
toPath := filepath.Join(destDir, fileName)
srcPath := filepath.Join(srcDir, fileName)
if move == "1" {
log.Printf("Move file: %s\n", fileName)
err := os.Rename(srcPath, toPath)
if err != nil {
log.Printf("Failed to move the file: %s\n", err)
}
} else {
if _, err := os.Stat(toPath); err == nil {
// 如果存在
err := os.Remove(srcPath)
if err != nil {
return
}
fmt.Printf("Deleted: %s\n", file.Name())
} else {
// 不存在
srcPath := filepath.Join(srcDir, fileName)
// 复制文件
if err := copyFile(srcPath, toPath); err != nil {
fmt.Println("Failed to copy:", err)
return
}
// 删除源文件
if err := os.Remove(srcPath); err != nil {
fmt.Println("Failed to delete the original file:", err)
return
}
}
}
}
}
func copyFile(src, dest string) error {
// 打开源文件
srcFile, err := os.Open(src)
if err != nil {
log.Fatalf("Error opening source file: %v", err)
return err
}
defer srcFile.Close()
// 创建目标文件
dstFile, err := os.Create(dest)
if err != nil {
log.Fatalf("Error creating destination file: %v", err)
return err
}
defer dstFile.Close()
// 使用 bufio.NewReader 来提高读取性能
reader := bufio.NewReader(srcFile)
// 复制文件内容
_, err = io.Copy(dstFile, reader)
if err != nil {
log.Fatalf("Error copying file: %v", err)
return err
}
log.Println("File copied successfully")
return nil
}
本文作者:南月星河
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!