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")
    }
  • 相关阅读:
    [TCP/IP] HTTPS的工作原理
    [TCP/IP] SSL的通讯原理
    ESLint笔记
    MacBook Pro维修过程
    论前端工程化
    听书,怅然若失
    js实现Mac触摸板双指事件(上/下/左/右/放大/缩小)
    Windows和Mac浏览器启动本地程序
    科目三(番禺化龙展贸东路)考试录20170224
    写jQuery插件该注意的
  • 原文地址:https://www.cnblogs.com/majiang/p/14175118.html
Copyright © 2011-2022 走看看