Maison > développement back-end > Golang > Comment puis-je décompresser efficacement des fichiers dans Go et éviter les erreurs courantes ?

Comment puis-je décompresser efficacement des fichiers dans Go et éviter les erreurs courantes ?

Linda Hamilton
Libérer: 2024-11-11 06:41:02
original
841 Les gens l'ont consulté

How can I unzip files in Go efficiently and prevent common errors?

Décompressez des fichiers sans effort avec Go

Décompresser des fichiers dans Go devrait être un jeu d'enfant, mais parfois vous rencontrez des obstacles. Explorons une solution simple pour décompresser efficacement les fichiers.

Code initial :

Vous avez présenté l'extrait de code suivant :

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
}
Copier après la connexion

Solution optimisée :

Pour améliorer le code initial, envisagez les améliorations suivantes :

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
    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)

        // Check for ZipSlip (Directory traversal)
        if !strings.HasPrefix(path, filepath.Clean(dest) + string(os.PathSeparator)) {
            return fmt.Errorf("illegal file path: %s", path)
        }

        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
}
Copier après la connexion

Améliorations :

  • Création du répertoire de destination : Si le répertoire de destination n'existe pas, il est créé avant la décompression.
  • Fermeture des descripteurs de fichiers : Pour éviter les problèmes de pile différée, une fermeture s'effectue le processus d'extraction et d'écriture des fichiers.
  • Prévention Zipslip : Une vérification garantit que les fichiers extraits restent dans le dossier de destination désigné.
  • Gestion des erreurs : Fermer () les opérations sont gérées avec error panic() pour les meilleures pratiques.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal