如何使用Golang创建嵌入目录的副本?

huangapple go评论84阅读模式
英文:

How to create a copy of an embed directory using Golang?

问题

我正在创建一个命令行工具,其中一个任务是创建一个新目录并将一些文件放入其中。一些文件存储在我的源代码中,并使用嵌入包将其嵌入到二进制文件中,如下所示:

//go:embed assets
var assets embed.FS

我的文件系统树如下所示:

/
  /assets
    /foo
       foo.txt
       bar.txt
    hello.txt
    goodbye.txt
  main.go

因此,当我运行我的应用程序时,我需要将assets/foo中的内容复制到新生成的目录中。

我已经完成了以下代码:

func copyDir(origin, dirName string) {
	file, err := assets.Open(origin)
	if err != nil {
		internal.CleanUp(err)
	}
	fmt.Println(file)

	dir, err := cfg.FS.ReadDir(origin)
	if err != nil {
		internal.CleanUp(err)
	}
	fmt.Println(dir)
}


copyDir("assets/foo", "CopyFoo")

第一个参数是源路径,第二个参数是从我的CLI生成的新目录中的目标目录。

我需要的是一种将assets/foo中的内容复制到MyNewDirectory/CopyFoo的方法。

我有以下函数。它可以工作,但非常简单。我想知道是否有更好的方法来实现这个:

func copyDir(cfg *configs.ProjectConfig, origin, dirName string) {
	files, err := cfg.FS.ReadDir(origin)
	if err != nil {
		internal.CleanUp(err)
	}

	if _, err := os.Stat(fmt.Sprintf("%s/%s", cfg.Name, dirName)); os.IsNotExist(err) {
		os.MkdirAll(fmt.Sprintf("%s/%s", cfg.Name, dirName), os.ModePerm)
	}

	for _, file := range files {
		fileContent, err := cfg.FS.ReadFile(fmt.Sprintf("%s/%s", origin, file.Name()))
		if err != nil {
			internal.CleanUp(err)
		}

		filename := fmt.Sprintf("%s/%s/%s", cfg.Name, dirName, file.Name())
		f, err := os.Create(filename)
		if err != nil {
			log.Print("error os create")
			internal.CleanUp(err)
		}

		if _, err := f.Write(fileContent); err != nil {
			internal.CleanUp(err)
		}

		err = f.Close()
		if err != nil {
			internal.CleanUp(err)
		}
	}

}
英文:

I'm creating a CLI tool and one of the task I'm working on requires to create a new directory and put some files on it. Some files are stored on my source code and embed on the binary using the embed package as

//go:embed assets
var assets embed.FS

My fs tree looks like this:

/
  /assets
    /foo
       foo.txt
       bar.txt
    hello.txt
    goodbye.txt
  main.go

So when I run my app I need to copy the content from assets/foo into my new generated directory.

I have this so far:

func copyDir(origin, dirName string) {
	file, err := assets.Open(origin)
	if err != nil {
		internal.CleanUp(err)
	}
	fmt.Println(file)

	dir, err := cfg.FS.ReadDir(origin)
	if err != nil {
		internal.CleanUp(err)
	}
	fmt.Println(dir)
}


copyDir("assets/foo", "CopyFoo")

The first parameter is the source and the second one is the destination directory on the new generated directory from my CLI.

What I need is a way to copy the content from assets/foo into `MyNewDirectory/CopyFoo"

Edit

I have the following function. It works but its very simple. I wonder if there is a better way to do this:

func copyDir(cfg *configs.ProjectConfig, origin, dirName string) {
	files, err := cfg.FS.ReadDir(origin)
	if err != nil {
		internal.CleanUp(err)
	}

	if _, err := os.Stat(fmt.Sprintf("%s/%s", cfg.Name, dirName)); os.IsNotExist(err) {
		os.MkdirAll(fmt.Sprintf("%s/%s", cfg.Name, dirName), os.ModePerm)
	}

	for _, file := range files {
		fileContent, err := cfg.FS.ReadFile(fmt.Sprintf("%s/%s", origin, file.Name()))
		if err != nil {
			internal.CleanUp(err)
		}

		filename := fmt.Sprintf("%s/%s/%s", cfg.Name, dirName, file.Name())
		f, err := os.Create(filename)
		if err != nil {
			log.Print("error os create")
			internal.CleanUp(err)
		}

		if _, err := f.Write(fileContent); err != nil {
			internal.CleanUp(err)
		}

		err = f.Close()
		if err != nil {
			internal.CleanUp(err)
		}
	}

}

答案1

得分: 3

你可以用单个os.WriteFile()调用替换os.Create()f.Write()f.Close()的调用:

for _, file := range files {
    fileContent, err := cfg.FS.ReadFile(fmt.Sprintf("%s/%s", origin, file.Name()))
    if err != nil {
        internal.CleanUp(err)
    }

    filename := fmt.Sprintf("%s/%s/%s", cfg.Name, dirName, file.Name())
    if err := os.WriteFile(filename, fileContent, 0666); err != nil {
        log.Printf("error os.WriteFile error: %v", err)
        internal.CleanUp(err)
    }
}
英文:

You may substitute the os.Create(), f.Write() and f.Close() calls with a single os.WriteFile() call:

for _, file := range files {
    fileContent, err := cfg.FS.ReadFile(fmt.Sprintf("%s/%s", origin, file.Name()))
    if err != nil {
        internal.CleanUp(err)
    }

    filename := fmt.Sprintf("%s/%s/%s", cfg.Name, dirName, file.Name())
    if err := os.WriteFile(filename, fileContent, 0666); err != nil {
        log.Printf("error os.WriteFile error: %v", err)
        internal.CleanUp(err)
    }
}

huangapple
  • 本文由 发表于 2021年12月11日 18:55:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/70314526.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定