online mac lib gratis golang files go zip unzip

mac - Una manera fácil de descomprimir el archivo con Golang



unzip mac (4)

Estoy usando archive/zip paquete archive/zip para leer archivos .zip y copiar en el disco local. A continuación se muestra el código fuente para descomprimir archivos .zip para mis propias necesidades.

import ( "archive/zip" "io" "log" "os" "path/filepath" "strings" ) func unzip(src, dest string) error { r, err := zip.OpenReader(src) if err != nil { return err } defer r.Close() for _, f := range r.File { rc, err := f.Open() if err != nil { return err } defer rc.Close() fpath := filepath.Join(dest, f.Name) if f.FileInfo().IsDir() { os.MkdirAll(fpath, f.Mode()) } else { var fdir string if lastIndex := strings.LastIndex(fpath,string(os.PathSeparator)); lastIndex > -1 { fdir = fpath[:lastIndex] } err = os.MkdirAll(fdir, f.Mode()) if err != nil { log.Fatal(err) return err } f, err := os.OpenFile( fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err } defer f.Close() _, err = io.Copy(f, rc) if err != nil { return err } } } return nil }

¿Hay una manera fácil de descomprimir el archivo con Golang?

en este momento mi código es:

func Unzip(src, dest string) error { r, err := zip.OpenReader(src) if err != nil { return err } defer r.Close() for _, f := range r.File { rc, err := f.Open() if err != nil { return err } defer rc.Close() path := filepath.Join(dest, f.Name) if f.FileInfo().IsDir() { os.MkdirAll(path, f.Mode()) } else { f, err := os.OpenFile( path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err } defer f.Close() _, err = io.Copy(f, rc) if err != nil { return err } } } return nil }


He estado navegando un poco en Google y he encontrado repetidamente a personas que dicen que no hay ninguna biblioteca que pueda manejar eso. Tal vez me perdí un repositorio personalizado en mi búsqueda y alguien más lo encontrará para nosotros.

Puede usar io.Copy(src, dest) para facilitar el proceso, pero no lo he probado en absoluto.

Por ejemplo:

os.MkDirAll(dest, r.File.Mode) d, _ := os.Open(dest) io.Copy(r.File, d)

Honestamente, su código se ve muy bien y si yo mismo hiciera una función de Extraer (y lo anterior no funciona) entonces probablemente tomaría una página de su libro.


Preferiría usar 7zip con Go, que te daría algo como esto.

func extractZip() { fmt.Println("extracting", zip_path) commandString := fmt.Sprintf(`7za e %s %s`, zip_path, dest_path) commandSlice := strings.Fields(commandString) fmt.Println(commandString) c := exec.Command(commandSlice[0], commandSlice[1:]...) e := c.Run() checkError(e) }

Mejor código de ejemplo

Sin embargo, si no es posible usar 7zip, intente esto. Aplazar una recuperación para atrapar el pánico. ( Example )

func checkError(e error){ if e != nil { panic(e) } } func cloneZipItem(f *zip.File, dest string){ // Create full directory path path := filepath.Join(dest, f.Name) fmt.Println("Creating", path) err := os.MkdirAll(filepath.Dir(path), os.ModeDir|os.ModePerm) checkError(err) // Clone if item is a file rc, err := f.Open() checkError(err) if !f.FileInfo().IsDir() { // Use os.Create() since Zip don''t store file permissions. fileCopy, err := os.Create(path) checkError(err) _, err = io.Copy(fileCopy, rc) fileCopy.Close() checkError(err) } rc.Close() } func Extract(zip_path, dest string) { r, err := zip.OpenReader(zip_path) checkError(err) defer r.Close() for _, f := range r.File { cloneZipItem(f, dest) } }


Si no existe un retrabajo ligero de la solución del OP para crear el dest contiene el directorio, y para envolver la extracción / escritura del archivo en un cierre para eliminar el apilamiento de llamadas defer .Close() según @Nick Craig-Wood :

func Unzip(src, dest string) error { r, err := zip.OpenReader(src) if err != nil { return err } defer func() { if err := r.Close(); err != nil { panic(err) } }() os.MkdirAll(dest, 0755) // Closure to address file descriptors issue with all the deferred .Close() methods extractAndWriteFile := func(f *zip.File) error { rc, err := f.Open() if err != nil { return err } defer func() { if err := rc.Close(); err != nil { panic(err) } }() path := filepath.Join(dest, f.Name) if f.FileInfo().IsDir() { os.MkdirAll(path, f.Mode()) } else { os.MkdirAll(filepath.Dir(path), f.Mode()) f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err } defer func() { if err := f.Close(); err != nil { panic(err) } }() _, err = io.Copy(f, rc) if err != nil { return err } } return nil } for _, f := range r.File { err := extractAndWriteFile(f) if err != nil { return err } } return nil }

Nota: también se actualizó para incluir el manejo de errores Close () (si buscamos las mejores prácticas, es posible que sigamos TODAS).