• 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 
    ", file.Name, err)
                return
            }
            for _, content := range file.Content {
                _, err = f.Write([]byte(content + "
    "))
                if err != nil {
                    fmt.Printf("zip write content [%s] has error:%v
    ", content, err)
                }
     
            }
     
        }
        // 关闭压缩文档
        err := w.Close()
        if err != nil {
            fmt.Printf("zip close has error:%v
    ", 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
    ", err)
        }
        buf.WriteTo(f)
        fmt.Println("zip create done")
    }
     
    func ReadZip() {
        path := "./file.zip"
        if !IsExist(path) {
            fmt.Printf("zip  file [%s] not exist
    ", path)
            return
        }
        // 打开一个zip格式文件
        r, err := zip.OpenReader(path)
        if err != nil {
            fmt.Printf("zip read[OpenReader] has error:%v
    ", err)
            return
        }
        defer r.Close()
        // 迭代压缩文件中的文件,打印出文件中的内容
        for _, f := range r.File {
            fmt.Printf("ReadZip open file: %s
    ", 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
    ", 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 
    ", file.Name, err)
                return
            }
            for _, content := range file.Content {
                _, err = f.Write([]byte(content + "
    "))
                if err != nil {
                    fmt.Printf("tar write content [%s] has error:%v
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", name, rowindex, cellindex, cell.Value)
                }
            }
        }
        fmt.Println("read xlsx done")
    }
  • 相关阅读:
    【校招VIP】“推推”产品项目课程:产品的规划和商业化分析
    前端项目没亮点,校招简历过不了?速来围观(附项目代码讲解)
    【校招VIP】[前端][二本][7分]简历样式符合一线校招要求
    【校招VIP】“推推”产品项目课程:列表模块原型图
    产品项目没亮点,校招过不了,99%的人不知道问题出在了——产品脑图没有细化到具体的功能点
    【校招VIP】“推电影”第一期电影详情模块Java开发文档作业评审2
    【校招VIP】[前端][二本][6分]项目内容描述要更加细致
    PMP9.项目资源管理9.4建设团队
    PMP10.项目沟通管理10.1规划沟通管理
    PMP9.项目资源管理9.2估算活动资源
  • 原文地址:https://www.cnblogs.com/majiang/p/14177114.html
Copyright © 2020-2023  润新知