go文件操作實踐[讀寫zip tar xlsx文件]


這篇我接着實踐zip,tar和xlsx文件的讀寫操作。簡單介紹一下 tar吧:

tar 是一種打包格式,但不對文件進行壓縮,所以打包后的文檔一般遠遠大於 zip 和 tar.gz,因為不需要壓縮的原因,所以打包的速度是非常快的,打包時 CPU 占用率也很低。
tar 的目的在於方便文件的管理,比如在我們的生活中,有很多小物品分散在房間的各個角落,為了方便整潔可以將這些零散的物品整理進一個箱子中,而 tar 的功能就類似這樣。
創建 tar 歸檔文件與創建 .zip 歸檔文件非常類似,主要不同點在於我們將所有數據都寫入相同的 writer 中,並且在寫入文件的數據之前必須寫入完整的頭部,而非僅僅是一個文件名。
tar 打包實現原理如下:
創建一個文件 x.tar,然后向 x.tar 寫入 tar 頭部信息;
打開要被 tar 的文件,向 x.tar 寫入頭部信息,然后向 x.tar 寫入文件信息;
當有多個文件需要被 tar 時,重復第二步直到所有文件都被寫入到 x.tar 中;
關閉 x.tar,完成打包

package main
 
import (
    "archive/tar"
    "archive/zip"
    "bytes"
    "fmt"
    "io"
    "os"
    "strings"
 
    "github.com/tealeg/xlsx"
)
 
type Website struct {
    Name    string `xml:"name,attr"`
    Content []string
}
 
var info []Website
 
func init() {
    info = []Website{
        {"Golang.txt", []string{"http://c.biancheng.net/cplus/", "http://c.biancheng.net/linux_tutorial/"}},
        {"Java.txt", []string{"http://c.biancheng.net/socket/", "http://c.biancheng.net/python/"}},
    }
    /*
        列舉了一些常用的 flag 文件處理參數:
        O_RDONLY:只讀模式打開文件;
        O_WRONLY:只寫模式打開文件;
        O_RDWR:讀寫模式打開文件;
        O_APPEND:寫操作時將數據附加到文件尾部(追加);
        O_CREATE:如果不存在將創建一個新文件;
        O_EXCL:和 O_CREATE 配合使用,文件必須不存在,否則返回一個錯誤;
        O_SYNC:當進行一系列寫操作時,每次都要等待上次的 I/O 操作完成再進行;
        O_TRUNC:如果可能,在打開時清空文件。
    */
}
 
// 檢查文件或目錄是否存在
// 如果由 filename 指定的文件或目錄存在則返回 true,否則返回 false
func IsExist(filename string) bool {
    _, err := os.Stat(filename)
    return err == nil || os.IsExist(err)
}
func main() {
    WriteZip()
    ReadZip()
    WriteTar()
    ReadTar()
    WriteXlsx()
    ReadXlsx()
}
 
func WriteZip() {
    // 創建一個緩沖區用來保存壓縮文件內容
    buf := new(bytes.Buffer)
    // 創建一個壓縮文檔
    w := zip.NewWriter(buf)
    // 創建文件 寫入內容
    for _, file := range info {
        f, err := w.Create(file.Name)
        if err != nil {
            fmt.Printf("create zip fiel [%s] has error:%v \r\n", file.Name, err)
            return
        }
        for _, content := range file.Content {
            _, err = f.Write([]byte(content + "\r\n"))
            if err != nil {
                fmt.Printf("zip write content [%s] has error:%v\r\n", content, err)
            }
 
        }
 
    }
    // 關閉壓縮文檔
    err := w.Close()
    if err != nil {
        fmt.Printf("zip close has error:%v\r\n", err)
    }
    // 將壓縮文檔內容寫入文件
    path := "./file.zip"
    if IsExist(path) {
        os.Remove(path)
    }
    f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666)
    defer f.Close()
    if err != nil {
        fmt.Printf("zip create has error:%v\r\n", err)
    }
    buf.WriteTo(f)
    fmt.Println("zip create done")
}
 
func ReadZip() {
    path := "./file.zip"
    if !IsExist(path) {
        fmt.Printf("zip  file [%s] not exist\r\n", path)
        return
    }
    // 打開一個zip格式文件
    r, err := zip.OpenReader(path)
    if err != nil {
        fmt.Printf("zip read[OpenReader] has error:%v\r\n", err)
        return
    }
    defer r.Close()
    // 迭代壓縮文件中的文件,打印出文件中的內容
    for _, f := range r.File {
        fmt.Printf("ReadZip open file: %s\n", f.Name)
        rc, err := f.Open()
        if err != nil {
            fmt.Printf(err.Error())
        }
        _, err = io.CopyN(os.Stdout, rc, int64(f.UncompressedSize64))
        if err != nil {
            fmt.Printf(err.Error())
        }
        rc.Close()
    }
}
 
/*
tar 打包實現原理如下:
創建一個文件 x.tar,然后向 x.tar 寫入 tar 頭部信息;
打開要被 tar 的文件,向 x.tar 寫入頭部信息,然后向 x.tar 寫入文件信息;
當有多個文件需要被 tar 時,重復第二步直到所有文件都被寫入到 x.tar 中;
關閉 x.tar,完成打包。
*/
func WriteTar() {
    path := "./output.tar"
    if IsExist(path) {
        os.Remove(path)
    }
    f, err := os.Create(path) //創建一個 tar 文件
    if err != nil {
        fmt.Printf("create tar has error %v\r\n", err)
        return
    }
    defer f.Close()
    tw := tar.NewWriter(f)
    defer tw.Close()
 
    for _, file := range info {
        //preare file
        f, err := os.Create(file.Name)
 
        if err != nil {
            fmt.Printf("create tar fiel [%s] has error:%v \r\n", file.Name, err)
            return
        }
        for _, content := range file.Content {
            _, err = f.Write([]byte(content + "\r\n"))
            if err != nil {
                fmt.Printf("tar write content [%s] has error:%v\r\n", content, err)
            }
 
        }
        f.Close()
        ///
        fileInfo, _ := os.Stat("./" + file.Name)
        hdr, err := tar.FileInfoHeader(fileInfo, "")
        if err != nil {
            fmt.Println(err)
        }
        err = tw.WriteHeader(hdr) //寫入頭文件信息
        if err != nil {
            fmt.Println(err)
        }
        f1, err := os.Open("./" + file.Name)
        if err != nil {
            fmt.Println(err)
            return
        }
        m, err := io.Copy(tw, f1) //將main.exe文件中的信息寫入壓縮包中
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(m)
    }
    fmt.Println("tar wirte done")
 
}
 
func ReadTar() {
    path := "./output.tar"
    if !IsExist(path) {
        fmt.Printf("tar  file [%s] not exist\r\n", path)
        return
    }
    f, err := os.Open(path)
    if err != nil {
        fmt.Println("文件打開失敗", err)
        return
    }
    defer f.Close()
    r := tar.NewReader(f)
    for hdr, err := r.Next(); err != io.EOF; hdr, err = r.Next() {
        if err != nil {
            fmt.Println(err)
            return
        }
        fileinfo := hdr.FileInfo()
        fmt.Println(fileinfo.Name())
        /*
            f, err := os.Create("123" + fileinfo.Name())
            if err != nil {
                fmt.Println(err)
            }
            defer f.Close()
        */
        _, err = io.Copy(os.Stdout, r)
        if err != nil {
            fmt.Println(err)
        }
    }
}
 
func WriteXlsx() {
    path := "./info.xlsx"
    if IsExist(path) {
        os.Remove(path)
    }
    xlsxfile := xlsx.NewFile()
    ///創建sheet 寫入數據
    for _, file := range info {
        fileName := strings.Replace(file.Name, ".txt", "", 1)
        sheet, err := xlsxfile.AddSheet(fileName)
        if err != nil {
            fmt.Printf("xlsx create sheet [%s] has error %v\r\n", fileName, err)
            continue
        }
        row := sheet.AddRow()
        row.SetHeightCM(1)
        cell := row.AddCell()
        cell.Value = "Content"
        for _, content := range file.Content {
            addRow := sheet.AddRow()
            addCell := addRow.AddCell()
            addCell.Value = content
        }
    }
    err := xlsxfile.Save(path)
    if err != nil {
        fmt.Printf("xlsx save has error:%v\r\n", err)
    }
    fmt.Println("write xlsx done")
}
 
func ReadXlsx() {
    path := "./info.xlsx"
    if !IsExist(path) {
        return
    }
    // 讀取文件內容
    xlFile, err := xlsx.OpenFile(path)
    if err != nil {
        fmt.Printf("read xlsx has error %v\r\n", err)
    }
    for name, sheet := range xlFile.Sheet {
        fmt.Println(name)
        for rowindex, row := range sheet.Rows {
            for cellindex, cell := range row.Cells {
                fmt.Printf("sheet [%s] %d rows %d cell=%s\r\n", name, rowindex, cellindex, cell.Value)
            }
        }
    }
    fmt.Println("read xlsx done")
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM