es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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)
        }
    }
}
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución

    Para copiar el contenido de assets/foo a MyNewDirectory/CopyFoo, puedes crear el nuevo directorio usando os.MkdirAll() y luego recorrer los archivos en el directorio fuente usando cfg.FS.ReadDir(). Para cada archivo, puedes leer su contenido usando cfg.FS.ReadFile(), crear un nuevo archivo en el directorio de destino usando os.Create(), escribir el contenido en el nuevo archivo usando f.Write(), y luego cerrar el nuevo archivo usando f.Close().

    Aquí tienes una función de ejemplo que implementa este enfoque:

    func copyDir(cfg *configs.ProjectConfig, origen, nombreDir string) error {
        archivos, err := cfg.FS.ReadDir(origen)
        if err != nil {
            return err
        }
    
        dirDestino := filepath.Join(cfg.Name, nombreDir)
        if err := os.MkdirAll(dirDestino, os.ModePerm); err != nil {
            return err
        }
    
        for _, archivo := range archivos {
            rutaOrigen := filepath.Join(origen, archivo.Name())
            rutaDestino := filepath.Join(dirDestino, archivo.Name())
    
            contenidoArchivo, err := cfg.FS.ReadFile(rutaOrigen)
            if err != nil {
                return err
            }
    
            f, err := os.Create(rutaDestino)
            if err != nil {
                return err
            }
    
            if _, err := f.Write(contenidoArchivo); err != nil {
                return err
            }
    
            if err := f.Close(); err != nil {
                return err
            }
        }
    
        return nil
    }
    

    Esta función recibe el objeto cfg, que contiene el sistema de archivos incrustado, la ruta de origen (en este caso assets/foo), y el nombre del directorio de destino (dirName en este caso CopyFoo). 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í:

    err := copyDir(cfg, "assets/foo", "CopyFoo")
    if err != nil {
        // manejar el error
    }
    

    Esto creará un nuevo directorio MyNewDirectory/CopyFoo y copiará el contenido de assets/foo en él.

Comments are closed.