Tôi mới đến golang, và không thể tìm ra cách sử dụng gói "nén/gzip" của golang cho lợi thế của tôi. Về cơ bản, tôi chỉ muốn viết một cái gì đó vào một tập tin, gzip nó và đọc nó trực tiếp từ định dạng nén thông qua một kịch bản khác. Tôi thực sự sẽ đánh giá cao nếu ai đó có thể cho tôi một ví dụ về cách làm điều này.Tôi làm cách nào để sử dụng gói "nén/gzip" của golang để gzip một tệp?
Trả lời
Tất cả các gói nén đều triển khai cùng một giao diện. Bạn sẽ sử dụng một cái gì đó như thế này để nén:
var b bytes.Buffer
w := gzip.NewWriter(&b)
w.Write([]byte("hello, world\n"))
w.Close()
Và điều này để giải nén:
r, err := gzip.NewReader(&b)
io.Copy(os.Stdout, r)
r.Close()
cảm ơn! Điều này đã giúp. – pymd
Khá nhiều câu trả lời tương tự như Laurent, nhưng với file 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)
Bạn chỉ cần tạo tệp bằng os.Open và chuyển nó tới gzip.NewWriter và mọi ghi vào gzip writer đó sẽ ghi dữ liệu nén vào tệp đó. – Giacomo
Đối phần Đọc, một cái gì đó giống như hữu ích ioutil.ReadFile cho .gz tệp có thể là:
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
}
Tôi quyết định kết hợp các ý tưởng từ những câu trả lời khác và chỉ cung cấp một chương trình ví dụ đầy đủ. Rõ ràng có rất nhiều cách khác nhau để làm điều tương tự. Đây chỉ là một cách:
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
Có ví dụ đầy đủ như thế này sẽ hữu ích để tham khảo trong tương lai.
Tôi không nghĩ đây là một ví dụ hay; 'openFile' sẽ trả về' error'; không có điểm nào làm 'Stat' (cũng có thể là giá trị nil!); bất kỳ lỗi nào từ 'Write' và' Close' đều bị bỏ qua; v.v. –
Có, việc xử lý lỗi có thể được tăng cường một chút, nhưng nó dường như là một câu trả lời hợp lệ cho câu hỏi đang được hỏi. @DaveC – mdwhatcott
@DaveC, sau khi xem xét mã và xem xét đề xuất của bạn, tôi đã làm một chút viết lại. Đây chỉ là một ví dụ, nhưng hy vọng bản chỉnh sửa đã cải thiện các phương pháp hay nhất. Cảm ơn bạn đã phản hồi. – SunSparc
Ở đây func cho file gzip giải nén để file đích:
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
}
Tôi đang cố gắng hiểu giải pháp, bạn có thể nêu chi tiết tại sao chúng tôi cần io.Pipe ở đây không? – Sairam
@Sairam io.Pipe cho phép đọc nguồn, byte nguồn gzip và ghi vào đích khi đang di chuyển, mà không cần cấp phát thêm bộ nhớ cho nguồn và byte được mã hóa. –
- 1. Làm cách nào để tạo một gzip giống hệt nhau của cùng một tệp?
- 2. Làm cách nào để sử dụng gói openpgp của Go?
- 3. Làm cách nào để biên dịch gói Golang trên nền tảng Windows?
- 4. Tôi làm cách nào để sử dụng tệp jaxb.index?
- 5. Làm cách nào để gzip nén một chuỗi trong Perl
- 6. Làm cách nào để gzip nén một chuỗi bằng Python?
- 7. Làm cách nào để bật gzip?
- 8. Làm cách nào để nén nhiều tệp trong một tệp GZip bằng lớp GZipStream?
- 9. Tôi làm cách nào để sử dụng vim để chuyển đổi tệp của mình thành utf8?
- 10. Tôi làm cách nào để tìm gói của mình?
- 11. Làm cách nào để sử dụng một tệp từ dự án của tôi trong một tệp khác?
- 12. Cách sử dụng các tệp GZIP Trong Asp.net?
- 13. Làm cách nào để lập trình gzip trong Jetty?
- 14. Làm thế nào để sử dụng pip của Python để tải xuống và giữ các tệp nén cho một gói?
- 15. Tôi làm cách nào để tìm ra tên tệp của gói Perl?
- 16. Làm thế nào để tạo một gói Debian cho Ứng dụng Web Java của tôi?
- 17. Cách đặt dự án Golang (một bộ gói) vào Github?
- 18. Làm cách nào để nối văn bản vào một tệp trong golang?
- 19. Làm cách nào để đọc một dòng tệp gzip theo dòng?
- 20. Tôi làm cách nào để gói các thành phần để sử dụng trong nhiều ứng dụng iPhone?
- 21. Làm cách nào để sử dụng tệp .vimrc của tôi trong Cygwin?
- 22. Làm cách nào để sử dụng Chosen jQuery trong tệp html của tôi?
- 23. Làm cách nào để truy cập tệp trong gói OSGi?
- 24. Làm cách nào để tìm gói rpm nào cung cấp tệp tôi đang tìm?
- 25. Tôi làm cách nào để hiển thị gói DialogFragment sử dụng tính tương thích?
- 26. Tôi làm cách nào để sử dụng bản vá BigQuery?
- 27. Tôi làm cách nào để sử dụng gói appengine/urlfetch với goauth2?
- 28. Làm cách nào để phân phối ứng dụng Perl của tôi dưới dạng một tệp?
- 29. Mở gói các tệp lớn bằng gzip trong PHP
- 30. gzip một tệp trong Python
@Nicolai nhờ để chỉnh sửa câu hỏi. – pymd