zoukankan      html  css  js  c++  java
  • go 文件操作实践[读写json xlm gob txt]

    go常用操作文件有json,xml, gob 和txt,一般json,xml, gob 都是全部操作 很少修改一个部分快的内容, 所以一般采用 编码、解码实现,txt可能有追加所以相对难一点。 说说自己遇到的坑

    1.验证文件或者目录是否存在

    // 检查文件或目录是否存在
    // 如果由 filename 指定的文件或目录存在则返回 true,否则返回 false
    func IsExist(filename string) bool {
        _, err := os.Stat(filename)
        return err == nil || os.IsExist(err)
    }

    2在读取文本文件的时候 

    Readline读满缓冲区就返回,剩下的字节不会丢弃,留着下次读取。这样一行就拆分成了两次读取,两次读取出来的行都与预期的不符,后续的逻辑流程肯定也异常了
    解决方法:
    1.直接换成ReadBytes(’ n’) 或 ReadString(’ n’)
    2.对isPrefix返回值做校验

    3. os.OpenFile(filePath, os.O_RDWR|os.O_APPEND, 0666) 这个方法的flag一定要注意, 比如 设置成os.O_WRONLY|os.O_APPEND , 去读取文件, 结果是阻塞不是报错。

    整个dmeo 如下:

    package main
     
    import (
        "bufio"
        "encoding/gob"
        "encoding/json"
        "encoding/xml"
        "fmt"
        "io"
        "os"
    )
     
    type Website struct {
        Name   string `xml:"name,attr"`
        Url    string
        Course []string
    }
     
    var info []Website
     
    func init() {
        info = []Website{
            {"Golang", "http://c.biancheng.net/golang/", []string{"http://c.biancheng.net/cplus/", "http://c.biancheng.net/linux_tutorial/"}},
            {"Java", "http://c.biancheng.net/java/", []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() {
        WriteJson()
        ReadJson()
        WriteXml()
        ReadXML()
        WriteGob()
        ReadGob()
        WriteorCreatetxt()
        OpenAndAppendtxt()
        txtReadLine()
    }
     
    func WriteJson() {
        path := "./info.json"
        if IsExist(path) {
            os.Remove(path)
        }
        fileptr, err := os.Create(path)
        if err != nil {
            fmt.Printf("crete json file has error:%v
    ", err)
            return
        }
        defer fileptr.Close()
        encoder := json.NewEncoder(fileptr)
        err = encoder.Encode(info)
        if err != nil {
            fmt.Printf("json encode hase error %v
    ", err)
        } else {
            fmt.Println("json write done")
        }
    }
     
    func ReadJson() {
        path := "./info.json"
        fileptr, err := os.Open(path)
        if err != nil {
            fmt.Printf("open json file has error:%v
    ", err)
            return
        }
        defer fileptr.Close()
        var tmp []Website
        decoder := json.NewDecoder(fileptr)
        err = decoder.Decode(&tmp)
        if err != nil {
            fmt.Printf("json decode has error:%v
    ", err)
        }
        fmt.Println("json read done")
        fmt.Print(tmp)
    }
     
    func WriteXml() {
        path := "./info.xml"
        if IsExist(path) {
            os.Remove(path)
        }
        fileptr, err := os.Create(path)
        if err != nil {
            fmt.Printf("crete xml file has error:%v
    ", err)
            return
        }
        defer fileptr.Close()
        encoder := xml.NewEncoder(fileptr)
        err = encoder.Encode(info)
        if err != nil {
            fmt.Printf("xml encode hase error %v
    ", err)
        } else {
            fmt.Println("xml write done")
        }
    }
     
    func ReadXML() {
        path := "./info.xml"
        fileptr, err := os.Open(path)
        if err != nil {
            fmt.Printf("open xml file has error:%v
    ", err)
            return
        }
        defer fileptr.Close()
        var tmp []Website
        decoder := xml.NewDecoder(fileptr)
        err = decoder.Decode(&tmp)
        if err != nil {
            fmt.Printf("xml decode has error:%v
    ", err)
        }
        fmt.Println("xml read done")
        fmt.Print(tmp)
    }
     
    func WriteGob() {
        path := "./demo.gob"
        if IsExist(path) {
            os.Remove(path)
        }
        file, _ := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0777)
        defer file.Close()
        enc := gob.NewEncoder(file)
        if err := enc.Encode(info); err != nil {
            fmt.Printf("gob endcod  has err:%v", err)
        } else {
            fmt.Println("gob write don")
        }
    }
    func ReadGob() {
        path := "./demo.gob"
        fileptr, err := os.Open(path)
        if err != nil {
            fmt.Printf("open gob file has error:%v
    ", err)
            return
        }
        defer fileptr.Close()
        var tmp []Website
        decoder := gob.NewDecoder(fileptr)
        err = decoder.Decode(&tmp)
        if err != nil {
            fmt.Printf("gob decode has error:%v
    ", err)
        }
        fmt.Println("gob read done")
        fmt.Print(tmp)
    }
    func WriteorCreatetxt() {
        filePath := "./info.txt"
        file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
        if err != nil {
            fmt.Printf("txt open file has err:%v", err)
        }
        defer file.Close()
        //写入文件时,使用带缓存的 *Writer
        write := bufio.NewWriter(file)
        for i := 0; i < 5; i++ {
            write.WriteString(fmt.Sprintf("hello:%d 
    ", i+1))
        }
        //Flush将缓存的文件真正写入到文件中
        write.Flush()
        fmt.Println("txt write done")
    }
     
    func OpenAndAppendtxt() {
        filePath := "./info.txt"
        file, err := os.OpenFile(filePath, os.O_RDWR|os.O_APPEND, 0666)
        if err != nil {
            fmt.Printf("txt open file has err:%v", err)
        }
        defer file.Close()
        //读原来文件的内容,并且显示在终端
        reader := bufio.NewReader(file)
        for {
            str, err := reader.ReadString('
    ')
            if err == io.EOF {
                break
            }
            fmt.Print(str)
        }
        //写入文件时,使用带缓存的 *Writer
        write := bufio.NewWriter(file)
        for i := 0; i < 5; i++ {
            write.WriteString(fmt.Sprintf("world %d
    ", i+1))
        }
        //Flush将缓存的文件真正写入到文件中
        write.Flush()
        fmt.Println("txt append done")
    }
     
    /*
     Readline读满缓冲区就返回,剩下的字节不会丢弃,留着下次读取。
    这样一行就拆分成了两次读取,两次读取出来的行都与预期的不符,后续的逻辑流程肯定也异常了
    解决方法:
    1.直接换成ReadBytes(’ n’) 或 ReadString(’ n’)
    2.对isPrefix返回值做校验
    */
    func txtReadLine() {
        // 打开test.txt文件
        fi, err := os.Open("./test.txt")
        if err != nil {
            fmt.Println("open file error:", err)
            return
        }
        defer fi.Close()
     
        // 逐行读取记录
        br := bufio.NewReader(fi)
        var buf []byte
        for {
            line, prefix, err := br.ReadLine()
            if err == io.EOF {
                break
            }
     
            // 追加到自定义缓冲区内
            buf = append(buf, line...)
            // 如果prefix为真,则代表该行还有尚未读取完的数据,跳过后续具体操作,继续读取完该行剩余内容
            if prefix {
                continue
            }
            str := string(buf)
            fmt.Printf("--------------------
    ")
            fmt.Println("len(buf) = ", len(buf))
            fmt.Println("len(str) = ", len(str))
            fmt.Println(str)
            fmt.Printf("--------------------
    
    ")
            // 清空切片
            buf = append(buf[:0], buf[len(buf):]...)
        }
        fmt.Println("txt readline done")
    }
  • 相关阅读:
    如何使用SAP Intelligent Robotic Process Automation自动操作Excel
    OpenSAML 使用引导 IV: 安全特性
    Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务
    微服务架构集大成者—Spring Cloud (转载)
    Spring Cloud Eureka 服务注册列表显示 IP 配置问题
    使用 Notification API 开启浏览器桌面提醒
    SignalR 中使用 MessagePack 序列化提高 WebSocket 通信性能
    配置 Nginx 的目录浏览功能
    关于 Nginx 配置 WebSocket 400 问题
    Migrate from ASP.NET Core 2.0 to 2.1
  • 原文地址:https://www.cnblogs.com/majiang/p/14175118.html
Copyright © 2011-2022 走看看