Maison  >  Article  >  développement back-end  >  Pourquoi le report de la fermeture de gzip.NewWriter entraîne-t-il une perte de données dans Go ?

Pourquoi le report de la fermeture de gzip.NewWriter entraîne-t-il une perte de données dans Go ?

DDD
DDDoriginal
2024-10-25 22:47:29813parcourir

Why Does Deferring gzip.NewWriter Closure Cause Data Loss in Go?

La fermeture différée entraîne une perte de données dans gzip Writer

Lors de l'utilisation de gzip.NewWriter dans Go pour compresser une tranche d'octets, il est généralement observé que différer la fermeture de l'enregistreur entraîne une perte de données. Ce phénomène devient évident lors de la lecture des données compressées, car il se termine prématurément par une erreur de fin de fichier (EOF) inattendue.

Pour comprendre cela, examinons l'extrait de code fourni :

<code class="go">func zipData(originData []byte) ([]byte, error) {
    // Create a buffer to store the compressed data
    var bf bytes.Buffer
    
    // Initialize the gzip writer with the buffer
    gw := gzip.NewWriter(&bf)
    
    // Defer closure of the writer
    defer gw.Close()
    
    // Write the original data to the writer
    _, err := gw.Write(originData)
    if err != nil {
        return nil, err
    }
    
    // Flush the writer to write any buffered data
    if err = gw.Flush(); err != nil {
        return nil, err
    }
    
    // Return the compressed data
    return bf.Bytes(), nil
}</code>

Le problème vient de l'utilisation de defer pour fermer le rédacteur gzip (gw). Selon la documentation de Close() :

"Close ferme le Writer en vidant toutes les données non écrites vers le io.Writer sous-jacent et en écrivant le pied de page GZIP."

Dans ce cas, le différé La fermeture s'exécute après que la fonction ait renvoyé les données compressées stockées dans le tampon (bf). Cependant, le pied de page n'est pas écrit tant que la méthode Close() n'est pas invoquée, laissant les données compressées incomplètes lorsqu'elles sont renvoyées.

Ce problème peut être résolu en fermant manuellement l'enregistreur avant de renvoyer les données compressées :

<code class="go">func zipData(originData []byte) ([]byte, error) {
    // ... (same code as before) ...
    
    // Close the writer to write the footer
    if err := gw.Close(); err != nil {
        return nil, err
    }
    
    // Return the compressed data
    return bf.Bytes(), nil
}</code>

En fermant le rédacteur avant de revenir, le pied de page GZIP est écrit avec succès et les données compressées peuvent être lues sans rencontrer l'erreur EOF.

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!

Déclaration:
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