zoukankan      html  css  js  c++  java
  • Golang之读写文件

    本文对golang的读写文件的操作进行展示废话少说直接上代码:

    package main
    
    import (
        "bufio"
        "errors"
        "fmt"
        "io"
        "log"
        "os"
    )
    
    // 读取文件的各种方式
    //
    // 运行方式: go build main.go; ./main.exe
    
    // * 整个文件读到内存,适用于文件较小的情况
    func readAllIntoMemory(filename string) (content []byte, err error) {
        fp, err := os.Open(filename) // 获取文件指针
        if err != nil {
            return nil, err
        }
        defer fp.Close()
    
        fileInfo, err := fp.Stat()
        if err != nil {
            return nil, err
        }
        buffer := make([]byte, fileInfo.Size())
        _, err = fp.Read(buffer) // 文件内容读取到buffer中
        if err != nil {
            return nil, err
        }
        return buffer, nil
    }
    
    // * 一块一块地读取, 即给一个缓冲, 分多次读到缓冲中
    func readByBlock(filename string) (content []byte, err error) {
        fp, err := os.Open(filename) // 获取文件指针
        if err != nil {
            return nil, err
        }
        defer fp.Close()
    
        const bufferSize = 64 // 缓冲大小, 每次读取64个字节
    
        buffer := make([]byte, bufferSize)
        for {
            // 注意这里要取bytesRead, 否则有问题
            bytesRead, err := fp.Read(buffer) // 文件内容读取到buffer中
            content = append(content, buffer[:bytesRead]...)
            if err != nil {
                if err == io.EOF {
                    err = nil
                    break
                } else {
                    return nil, err
                }
            }
        }
        return
    }
    
    // 逐行读取, 一行是一个[]byte, 多行就是[][]byte
    func readByLine(filename string) (lines [][]byte, err error) {
        fp, err := os.Open(filename) // 获取文件指针
        if err != nil {
            return nil, err
        }
        defer fp.Close()
        bufReader := bufio.NewReader(fp)
    
        for {
            line, _, err := bufReader.ReadLine()
            if err != nil {
                if err == io.EOF {
                    err = nil
                    break
                }
            } else {
                lines = append(lines, line)
            }
        }
    
        return
    }
    
    // * simulate tail -n -f filename
    func readLikeTail(filename string, n int) (lines [][]byte, err error) {
        if n <= 0 {
            return nil, errors.New("argument error")
        }
        fp, err := os.Open(filename) // 获取文件指针
        if err != nil {
            return nil, err
        }
        defer fp.Close()
    
        offset, err := fp.Seek(0, io.SeekEnd)
        if err != nil {
            return nil, err
        }
    
        buffer := make([]byte, 1)
        count := 0
        for offset > 0 {
            offset--
            bytesRead, err := fp.ReadAt(buffer, offset)
            if err != nil {
                return nil, err
            }
    
            if buffer[0] == '
    ' { // 读到了一行
                count++
                lines = append(lines, buffer[:bytesRead])
                if count == n {
                    break
                }
            }
    
            fmt.Printf("buffer=%s
    ", buffer)
        }
    
        return
    }
    
    func main() {
        const testFileName = "ls-al.txt"
        // fmt.Println(file.GetCurrentDirectory())
    
        // *
        content, err := readAllIntoMemory(testFileName)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%s
    ", content)
    
        // *
        content, err = readByBlock(testFileName)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%s
    ", content)
    
        // *
        lines, err := readByLine(testFileName)
        if err != nil {
            log.Fatal(err)
        }
        for i, line := range lines {
            fmt.Printf("readByLine: %d %s
    ", i+1, line)
        }
    
        // *
        fmt.Println()
        lines, err = readLikeTail(testFileName, 3)
        for i, line := range lines {
            fmt.Printf("readLikeTail: %d %s
    ", i+1, line)
        }
    }

    写文件的操作:

    func writeToFile(msg string)  {
        f, err := os.OpenFile("/home/mingbai/del/koala.log", os.O_WRONLY&os.O_CREATE, 0666)
        if err != nil {
            log.Println(err.Error())
        }
    
        _, err = f.Write([]byte(msg))
        if err != nil {
            log.Println(err.Error())
        }
        f.Close()
    }

     解释:

    OpenFile 这个函数不那么好理解,解释一下. 第一个参数 就是文件路径.

    第二个参数是一个 文件打开方式的flag是读是写 还是读写;是追加还是清空等, 第一种类型同第二种类型可用'|' (与或非的或)操作连接,表示两个都要. 其实你还可以加三个,比如:os.O_WRONLY|os.O_CREATE|os.O_APPEND 表示写模式打开,没有则创建且追加的方式写入.

    第三个参数是操作文件的权限, 就是Linux 文件权限的那种4 读,2 写, 1 执行; 可累加.比较常见,不多解释了.

  • 相关阅读:
    UC将发布高性能HTML5游戏引擎XCanvas
    一台晚会3.15拯救不了这些高科技公司
    4G时代更有利于TDD的发展
    【leetcode】Binary Tree Zigzag Level Order Traversal
    四月电商价格战火重燃 服务为决胜之道
    linux sysfs(3)
    ubuntu gedit 中文显示乱码解决方法
    研究人员将Windows Phone 7和Windows Azure推广到平流层的大气污染研究中
    迁移周系列II/II: On Premises 迁移视频
    玩Rock, Paper, Azure Challenge,赢取免费Kinect和Xbox 360!
  • 原文地址:https://www.cnblogs.com/wanghuixi/p/13253100.html
Copyright © 2011-2022 走看看