Golang实现递归复制文件夹

代码

go 复制代码
package zdpgo_file

import (
	"errors"
	"os"
	"path/filepath"
	"strings"
)

// CopyDir 复制文件夹
// @param srcPath 源文件夹
// @param desPath 目标文件夹
// @return error 错误信息
func CopyDir(srcPath, desPath string) error {
	// 检查目录是否正确
	if !IsDir(srcPath) {
		return errors.New("要复制的文件夹不存在")
	}

	// 源文件夹和目标文件夹不能相同
	if strings.TrimSpace(srcPath) == strings.TrimSpace(desPath) {
		return errors.New("源文件夹和目标文件夹不能相同")
	}

	// 创建目标文件夹
	if !IsDir(desPath) {
		err := AddDir(desPath)
		if err != nil {
			return err
		}
	}

	// 路径规范
	srcPath = strings.Replace(srcPath, "\\", "/", -1)
	desPath = strings.Replace(desPath, "\\", "/", -1)

	// 遍历源文件夹
	err := filepath.Walk(srcPath, func(path string, f os.FileInfo, err error) error {
		if f == nil {
			return err
		}

		// 复制目录是将源目录中的子目录复制到目标路径中,不包含源目录本身
		if path == srcPath {
			return nil
		}

		// 生成新路径
		destNewPath := desPath + "/" + path
		destNewPath = strings.Replace(destNewPath, "\\", "/", -1)

		// 如果发生了递归,则退出
		if strings.Count(destNewPath, desPath) > 1 {
			return nil
		}

		// 如果是文件:复制文件
		// 如果是文件夹:不存在就创建新文件夹
		if !f.IsDir() {
			err = CopyFile(path, destNewPath)
			if err != nil {
				return err
			}
		} else {
			if !IsExist(destNewPath) {
				return AddDir(destNewPath)
			}
		}

		return nil
	})

	// 返回
	return err
}

测试

go 复制代码
package zdpgo_file

import "testing"

func TestCopyDir(t *testing.T) {
	if err := AddDir("test"); err != nil {
		t.Fatal(err)
	}

	data := []struct {
		Src string
		Dst string
	}{
		{".", "test/test2"},
		{"test/test2", "test/test1"},
	}

	for _, tt := range data {
		v := CopyDir(tt.Src, tt.Dst)
		if v != nil {
			t.Error(v)
		}
	}
}

测试结果

相关推荐
无限进步_6 分钟前
【C++】巧用静态变量与构造函数:一种非常规的求和实现
开发语言·c++·git·算法·leetcode·github·visual studio
Advancer-9 分钟前
RedisTemplate 两种序列化实践方案
java·开发语言·redis
郝学胜-神的一滴17 分钟前
Socket实战:从单端聊天到多用户连接的实现秘籍
服务器·开发语言·python·网络协议·pycharm
元宝骑士19 分钟前
深度解析 ROW_NUMBER() 窗口函数:从入门到实战避坑指南
后端·mysql
小超超爱学习993723 分钟前
大数乘法,超级简单模板
开发语言·c++·算法
java1234_小锋28 分钟前
Java高频面试题:MyBatis如何实现动态数据源切换?
java·开发语言·mybatis
knighthood200132 分钟前
Qt5.15+VTK9.3.0实现点云点选功能
开发语言·qt
墨神谕36 分钟前
Java中,为什么要将.java文件编译成,class文件,而不是直接将.java编译成机器码
java·开发语言
段小二1 小时前
Token 费用失控、VIP 用户体验一样烂:Context Engineering 才是关键
人工智能·后端
Nyarlathotep01131 小时前
并行设计模式(3):Future模式
java·后端