Подтвердить что ты не робот

Как использовать golang пакет "compress/gzip" для gzip файла?

Я новичок в golang и не могу понять, как использовать golang "compress/gzip" в свою пользу. В принципе, я просто хочу написать что-то в файл, gzip и прочитать его прямо из зашифрованного формата через другой script. Я был бы очень признателен, если бы кто-нибудь мог дать мне пример о том, как это сделать.

4b9b3361

Ответ 1

Все пакеты сжатия реализуют один и тот же интерфейс. Вы должны использовать что-то вроде этого для сжатия:

var b bytes.Buffer
w := gzip.NewWriter(&b)
w.Write([]byte("hello, world\n"))
w.Close()

И это для распаковки:

r, err := gzip.NewReader(&b)
io.Copy(os.Stdout, r)
r.Close()

Ответ 2

Для части Read что-то вроде полезного ioutil.ReadFile для файлов .gz может быть:

func ReadGzFile(filename string) ([]byte, error) {
    fi, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    defer fi.Close()

    fz, err := gzip.NewReader(fi)
    if err != nil {
        return nil, err
    }
    defer fz.Close()

    s, err := ioutil.ReadAll(fz)
    if err != nil {
        return nil, err
    }
    return s, nil   
}

Ответ 3

В значительной степени тот же ответ, что и Лоран, но с файлом io:

import (
  "bytes"
  "compress/gzip"
  "io/ioutil"
)
// ...
var b bytes.Buffer
w := gzip.NewWriter(&b)
w.Write([]byte("hello, world\n"))
w.Close() // You must close this first to flush the bytes to the buffer.
err := ioutil.WriteFile("hello_world.txt.gz", b.Bytes(), 0666)

Ответ 4

Я решил объединить идеи из других ответов и просто предоставить полную примерную программу. Очевидно, есть много разных способов сделать то же самое. Это один из способов:

package main

import (
    "compress/gzip"
    "fmt"
    "io/ioutil"
    "os"
)

var zipFile = "zipfile.gz"

func main() {
    writeZip()
    readZip()
}

func writeZip() {
    handle, err := openFile(zipFile)
    if err != nil {
        fmt.Println("[ERROR] Opening file:", err)
    }

    zipWriter, err := gzip.NewWriterLevel(handle, 9)
    if err != nil {
        fmt.Println("[ERROR] New gzip writer:", err)
    }
    numberOfBytesWritten, err := zipWriter.Write([]byte("Hello, World!\n"))
    if err != nil {
        fmt.Println("[ERROR] Writing:", err)
    }
    err = zipWriter.Close()
    if err != nil {
        fmt.Println("[ERROR] Closing zip writer:", err)
    }
    fmt.Println("[INFO] Number of bytes written:", numberOfBytesWritten)

    closeFile(handle)
}

func readZip() {
    handle, err := openFile(zipFile)
    if err != nil {
        fmt.Println("[ERROR] Opening file:", err)
    }

    zipReader, err := gzip.NewReader(handle)
    if err != nil {
        fmt.Println("[ERROR] New gzip reader:", err)
    }
    defer zipReader.Close()

    fileContents, err := ioutil.ReadAll(zipReader)
    if err != nil {
        fmt.Println("[ERROR] ReadAll:", err)
    }

    fmt.Printf("[INFO] Uncompressed contents: %s\n", fileContents)

    // ** Another way of reading the file **
    //
    // fileInfo, _ := handle.Stat()
    // fileContents := make([]byte, fileInfo.Size())
    // bytesRead, err := zipReader.Read(fileContents)
    // if err != nil {
    //     fmt.Println("[ERROR] Reading gzip file:", err)
    // }
    // fmt.Println("[INFO] Number of bytes read from the file:", bytesRead)

    closeFile(handle)
}

func openFile(fileToOpen string) (*os.File, error) {
    return os.OpenFile(fileToOpen, openFileOptions, openFilePermissions)
}

func closeFile(handle *os.File) {
    if handle == nil {
        return
    }

    err := handle.Close()
    if err != nil {
        fmt.Println("[ERROR] Closing file:", err)
    }
}

const openFileOptions int = os.O_CREATE | os.O_RDWR
const openFilePermissions os.FileMode = 0660

Наличие полного примера, подобного этому, должно быть полезно для использования в будущем.

Ответ 5

Здесь func для распаковки файла gzip в файл назначения:

func UnpackGzipFile(gzFilePath, dstFilePath string) (int64, error) {
    gzFile, err := os.Open(gzFilePath)
    if err != nil {
        return 0, fmt.Errorf("Failed to open file %s for unpack: %s", gzFilePath, err)
    }
    dstFile, err := os.OpenFile(dstFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0660)
    if err != nil {
        return 0, fmt.Errorf("Failed to create destination file %s for unpack: %s", dstFilePath, err)
    }

    ioReader, ioWriter := io.Pipe()

    go func() { // goroutine leak is possible here
        gzReader, _ := gzip.NewReader(gzFile)
        // it is important to close the writer or reading from the other end of the
        // pipe or io.copy() will never finish
        defer func(){
            gzFile.Close()
            gzReader.Close()
            ioWriter.Close()
        }()

        io.Copy(ioWriter, gzReader)
    }()

    written, err := io.Copy(dstFile, ioReader)
    if err != nil {
        return 0, err // goroutine leak is possible here
    }
    ioReader.Close()
    dstFile.Close()

    return written, nil
}