[GO language foundation] GO file operation, input stream and output stream (11)

Article Directory

File operations

  • The concept of a fileA
    file is a type of data source (a place where data is saved).The main function of a file is to save data.
  • Input stream and output stream
  1. Flow: the path that data travels between the data source (file) and the program (memory)
  2. Input stream: the path of data from the data source (file) to the program (memory)
  3. Output stream: the path of data from the program (memory) to the data source (file)
  • os.File
    os.File encapsulates all file-related operations, File is a structure
    type File 
    type File struct { 
    // 内含隐藏或非导出字段 
    } 
    //File代表一个打开的文件对象。
  • Basic functions of files
  1. create a new file
    func Create(filename string) (file *File, err Error)

Create a new file according to the provided file name, and return a file object. The default permission is 0666. The returned file object is readable and writable.

    func NewFile(fd uintptr, filename string) *File

Create the corresponding file according to the file descriptor and return a file object

  1. open a file
    func Open(filename string) (file *File, err error)

Open opens a file for reading. If the operation is successful, the method of the returned file object can be used to read the data; the corresponding file descriptor has the O_RDONLY mode. If there is an error, the underlying type of the error is *PathError.
This method opens a file named filename, but it is read-only. The internal implementation actually calls OpenFile.

    func OpenFile(filename string, flag int, perm uint32) (file *File, err Error)

OpenFile is mainly used to specify parameters (os.O_APPEND|os.O_CREATE|os.O_WRONLY) and file permissions (0666) to open the file. If the file is successfully opened, the returned file object will be used as an I/O operation, and flag is the way to open , Read-only, read-write, etc., perm is the permission

  1. Write file
    func (file *File) Write(b []byte) (n int, err Error)

The write length is b bytes and slices into file f, and the written byte number and error information are returned. When n is not equal to len(b), non-empty err will be returned

    func (file *File) WriteAt(b []byte, off int64) (n int, err Error)

Write bytes of length b to file f at offset off

    func (file *File) WriteString(s string) (ret int, err Error)

Similar to the Write method, but the content is written as a string instead of byte slices

    bufio.NewWriter(w io.Writer) *Writer

    举例:
    writer := bufio.NewWriter(file)
    // 使用for循环写入内容
    for i := 0; i < 3; i++ {
        _, err := writer.WriteString(str) // func (b *Writer) WriteString(s string) (int, error)
        if err != nil {
            fmt.Printf("文件写入出错:%s", err)
        }
    }

Buffered write

    err = ioutil.WriteFile(filePath, content, 0666)
    if err != nil {
        fmt.Printf("写入文件出错:%v", err)
        return
    }

Use the ioutil.WriteFile method to write to the file, which is to write the content of []byte into the file. If there is no newline character in the content string, there will be no newline character by default. If the file does not exist, the file will be created according to the given permissions. Otherwise, clear the file before writing the data.

  1. Read file
func (file *File) Read(b []byte) (n int, err Error)

Read bytes of length b from the file object, return the number of bytes currently read and error information. Therefore, to use this method, you need to initialize an empty byte list that matches the size of the content. When the end of the file is read, the method returns 0, io.EOF

func (file *File) ReadAt(b []byte, off int64) (n int, err Error)

Read bytes of length b from the off offset of the file. Returns the number of bytes read and error information. When the number of bytes read n is less than the length len(b) of the bytes to be read, this method will return a non-empty error. When the end of the file is read, err returns io.EOF

    bufio.NewReader(rd io.Reader) *Reader

    举例:
    reader := bufio.NewReader(file)
    for {
        line, err := reader.ReadString('\n') // 读到一个换行符就结束
        if err == io.EOF { // io.EOF表示文件的末尾
            break
        }
    }

Buffer mode read (default buffer is 4096 bytes)

    func ReadFile(filename string) ([]byte, error)

    举例:
    content, err := ioutil.ReadFile(filePath)
    if err != nil {
        // log.Fatal(err)
        fmt.Printf("读取文件出错:%v", err)
    }

Use the io/ioutil.ReadFile method to read the file into memory at once

  1. Determine whether the file exists

The way golang judges whether a file or folder exists is to use the error value returned by the os.Stat() function to judge:

  1. If the returned error is nil, the file or folder exists;
  2. If the returned error type is judged to be true using os.IsNotExist(), it means that the file or folder does not exist;
    3. If the returned error is of another type, it is uncertain whether it exists.
  1. Close file
    func (f *File) Close() error

Close closes the file f so that the file cannot be used for reading or writing. It returns possible errors.

  1. Copy files
    func Copy(dst Writer, src Reader) (written int64, err error)

    举例:
    // 将 srcFilePath 拷贝到 dstFilePath
    func CopyFile(dstFilePath string, srcFilePath string) (written int64, err error) {
        // 打开srcFilePath
        srcFile, err := os.Open(srcFilePath)
        if err != nil {
            fmt.Printf("打开文件出错:%s\n", err)
            return
        }
        defer srcFile.Close()
        // 通过 bufio/NewReader,传入 srcFile,获取到 reader
        reader := bufio.NewReader(srcFile)
        // 打开dstFilePath
        dstFile, err := os.OpenFile(dstFilePath, os.O_WRONLY | os.O_CREATE, 0666)
        if err != nil {
            fmt.Printf("打开文件出错:%s\n", err)
            return
        }
        defer dstFile.Close()
        // 通过 bufio/NewWriter,传入 dstFile,获取到 writer
        writer := bufio.NewWriter(dstFile)
        return io.Copy(writer, reader)
    }
    func main() {
        srcFilePath := "e:/a.mp4"
        dstFilePath := "f:/b.mp4"
        _, err := CopyFile(dstFilePath, srcFilePath)
        if err != nil {
            fmt.Printf("拷贝文件出错:%s", err)
        }
        fmt.Println("拷贝文件完成")
    }

Copy src data to dst until EOF is reached on src or an error occurs. Returns the number of bytes copied and the first error encountered.

  1. Delete Files
    func Remove(name string) Error

Call this function to delete the file named name

  1. http
    package main
    import (
        "os"
        "io"
        "net/http"
        "net/url"
        "strconv"
        )

    func main() {
        f, err := os.OpenFile("./chrome_installer.exe", os.O_RDWR|os.O_CREATE, 0666) //O_RDWR|O_CREATE,也就是文件不存在的情况下就建一个空文件,因为windows下还有BUG,如果使用这个O_CREATE,就会直接清空文件,所以windows不用这个标志,你自己事先建立好文件。
        if err != nil {
            panic(err)
        }
        stat, err := f.Stat() //获取文件状态
        if err != nil {
            panic(err)
        }
        f.Seek(stat.Size(), 0) //把文件指针指到文件末,当然你说为何不直接用 O_APPEND 模式打开,没错是可以。我这里只是试验。
        //f.Seek(int64(os.O_APPEND), 0)
        url1 := "http://dl.google.com/chrome/install/696.57/chrome_installer.exe"
        var req http.Request
        req.Method = "GET"
        //req.UserAgent = UA  //客户端信息字符串,不过我加上UserAgent,一直报错,不知道怎么回事,暂时不用它
        req.Close = true
        req.URL, err = url.Parse(url1)
        if err != nil {
            panic(err)
        }
        header := http.Header{}
        header.Set("Range", "bytes="+strconv.FormatInt(stat.Size(), 10)+"-")
        req.Header = header
        resp, err := http.DefaultClient.Do(&req)
        if err != nil {
            panic(err)
        }
        written, err := io.Copy(f, resp.Body)
        if err != nil {
            panic(err)
        }
        println("written: ", written)
    }

  • Common operations
  1. Traverse a directory
    func main() {
        fmt.Println("请输入一个目录的路径:")
        var path string
        _, _ = fmt.Scan(&path)
        // 打开目录
        f, err := os.OpenFile(path, os.O_RDONLY, os.ModeDir)
        if err != nil {
            fmt.Printf("Open file failed:%s.\n", err)
            return
        }
        defer f.Close()
        // 读取目录
        info, err := f.Readdir(-1) // -1 表示读取目录中所有目录项
        // 遍历返回的切片
        for _, fileInfo := range info {
            if fileInfo.IsDir() {
                fmt.Printf("%s是一个目录\n", fileInfo.Name())
            } else {
                fmt.Printf("%s是一个文件\n", fileInfo.Name())
            }
        }
    }

  1. Count the number of English, numbers, spaces and other characters contained in a file.
    // 定义一个结构体,用于保存统计结果
    type CharCount struct {
        AlphaCount     int // 记录英文个数
        NumCount     int // 记录数字的个数
        SpaceCount     int // 记录空格的个数
        OtherCount     int // 记录其它字符的个数
    }

    func main() {
        // 思路: 打开一个文件, 创一个 reader
        // 每读取一行,就去统计该行有多少个 英文、数字、空格和其他字符
        // 然后将结果保存到一个结构体
        filePath := "e:/a.txt"
        file, err := os.Open(filePath)
        if err != nil {
            fmt.Printf("打开文件出错:%s\n", err)
            return
        }
        defer file.Close()
        // 定义一个 CharCount 实例
        var count CharCount
        //创建一个Reader
        reader := bufio.NewReader(file)
        // 开始循环的读取文件的内容
        for {
            line, err := reader.ReadString('\n')
            if err == io.EOF { // 读到文件末尾就退出
                break
            }
            // 遍历每一行(line),进行统计
            for _, v := range line {
                switch {
                    case v >= 'a' && v <= 'z':
                        fallthrough // 穿透
                    case v >= 'A' && v <= 'Z':
                        count.AlphaCount++
                    case v >= '0' && v <= '9':
                        count.NumCount++
                    case v == ' ' || v == '\t':
                        count.SpaceCount++
                    default :
                        count.OtherCount++
                }
            }
        }
        // 输出统计的结果看看是否正确
        fmt.Printf("字符的个数为:%v\n数字的个数为:%v\n空格的个数为:%v\n其它字符个数:%v\n",
            count.AlphaCount, count.NumCount, count.SpaceCount, count.OtherCount)
    }

Guess you like

Origin blog.csdn.net/weixin_54707168/article/details/114005999