Cómo crear una copia de un directorio incrustado utilizando Golang?
Estoy creando una herramienta de línea de comandos (CLI) y una de las tareas en las que estoy trabajando requiere crear un nuevo directorio y colocar algunos archivos en él. Algunos archivos están almacenados en mi código fuente y se incluyen en el binario utilizando el paquete embed de la siguiente manera:
//go:embed assets
var assets embed.FS
Mi estructura de archivos se ve así:
/
/assets
/foo
foo.txt
bar.txt
hello.txt
goodbye.txt
main.go
Entonces, cuando ejecuto mi aplicación, necesito copiar el contenido de assets/foo
en mi nuevo directorio generado.
Hasta ahora, tengo esto:
func copyDir(origen, nombreDirectorio string) {
archivo, err := assets.Open(origen)
if err != nil {
internal.CleanUp(err)
}
fmt.Println(archivo)
directorio, err := cfg.FS.ReadDir(origen)
if err != nil {
internal.CleanUp(err)
}
fmt.Println(directorio)
}
copyDir("assets/foo", "CopiarFoo")
El primer parámetro es la fuente y el segundo es el directorio de destino en el nuevo directorio generado por mi CLI.
Lo que necesito es una forma de copiar el contenido de assets/foo
en MiNuevoDirectorio/CopiarFoo
.
Edit:
Tengo la siguiente función. Funciona, pero es muy simple. Me pregunto si hay una mejor manera de hacer esto:
func copyDir(cfg *configs.ProjectConfig, origen, nombreDirectorio string) {
archivos, err := cfg.FS.ReadDir(origen)
if err != nil {
internal.CleanUp(err)
}
if _, err := os.Stat(fmt.Sprintf("%s/%s", cfg.Name, nombreDirectorio)); os.IsNotExist(err) {
os.MkdirAll(fmt.Sprintf("%s/%s", cfg.Name, nombreDirectorio), os.ModePerm)
}
for _, archivo := range archivos {
contenidoArchivo, err := cfg.FS.ReadFile(fmt.Sprintf("%s/%s", origen, archivo.Name()))
if err != nil {
internal.CleanUp(err)
}
nombreArchivo := fmt.Sprintf("%s/%s/%s", cfg.Name, nombreDirectorio, archivo.Name())
f, err := os.Create(nombreArchivo)
if err != nil {
log.Print("error al crear el archivo")
internal.CleanUp(err)
}
if _, err := f.Write(contenidoArchivo); err != nil {
internal.CleanUp(err)
}
err = f.Close()
if err != nil {
internal.CleanUp(err)
}
}
}
davy.ai
Solución
Para copiar el contenido de
assets/foo
aMyNewDirectory/CopyFoo
, puedes crear el nuevo directorio usandoos.MkdirAll()
y luego recorrer los archivos en el directorio fuente usandocfg.FS.ReadDir()
. Para cada archivo, puedes leer su contenido usandocfg.FS.ReadFile()
, crear un nuevo archivo en el directorio de destino usandoos.Create()
, escribir el contenido en el nuevo archivo usandof.Write()
, y luego cerrar el nuevo archivo usandof.Close()
.Aquí tienes una función de ejemplo que implementa este enfoque:
Esta función recibe el objeto
cfg
, que contiene el sistema de archivos incrustado, la ruta deorigen
(en este casoassets/foo
), y el nombre del directorio de destino (dirName
en este casoCopyFoo
). Devuelve un error si alguna de las operaciones de archivos falla.Luego puedes llamar a esta función en tu aplicación de línea de comandos así:
Esto creará un nuevo directorio
MyNewDirectory/CopyFoo
y copiará el contenido deassets/foo
en él.