Getting to Know Go Language 22 - Common Standard Libraries [I/O Operations]


I/O operations

formatted output

output format output content
%t word true or false
%b represented as binary
%d expressed as decimal
%e (=%.6e) scientific notation with 6 decimal places, such as -1234.456e+78
%f (=%.6f) has 6 decimal places, such as 123.456123
%g Use %e or %f format as appropriate (for more concise and accurate output)
%s Output string or byte array directly
%v The default format representation of the value
%+v Similar to %v, but the field name will be added when outputting the structure
%#v Go-syntax representation of the value
%T The Go-syntax representation of the value's type

standard input

fmt.Println("please input two word")
var word1 string 
var word2 string
fmt.Scan(&word1, &word2) //读入多个单词,空格分隔。如果输入了更多单词会被缓存起来,丢给下一次scan

fmt.Println("please input an int")
var i int
fmt.Scanf("%d", &i) //类似于Scan,转为特定格式的数据

The underlying principle of input and output

  • The terminal is actually a file, the relevant examples are as follows:
    • os.Stdin: The file instance of standard input, of type*File
    • os.Stdout: File instance for standard output, of type*File
    • os.Stderr: File instance for standard error output, of type*File

Operate the terminal as a file:

package main

import "os"

func main() {
    
    
    var buf [16]byte
    os.Stdin.Read(buf[:])
    os.Stdin.WriteString(string(buf[:]))
}

File operation related API

  • func Create(name string) (file *File, err Error)
    
    • Create a new file according to the provided file name, return a file object, the default permission is 0666
  • func NewFile(fd uintptr, name string) *File
    
    • Create the corresponding file according to the file descriptor and return a file object
  • func Open(name string) (file *File, err Error)
    
    • Open a file named name in read-only mode
  • func OpenFile(name string, flag int, perm uint32) (file *File, err Error)
    
    • Open the file named name, flag is the opening method, read-only, read-write, etc., perm is the permission
  • func (file *File) Write(b []byte) (n int, err Error)
    
    • Write byte type information to the file
  • func (file *File) WriteAt(b []byte, off int64) (n int, err Error)
    
    • Start writing byte type information at the specified position
  • func (file *File) WriteString(s string) (ret int, err Error)
    
    • Write string information to file
  • func (file *File) Read(b []byte) (n int, err Error)
    
    • read data into b
  • func (file *File) ReadAt(b []byte, off int64) (n int, err Error)
    
    • Read data from off to b
  • func Remove(name string) Error
    
    • delete the file named name

Open and close files

os.Open()Function capable of opening a file, returning one *Fileand one err. Calling the close() method on the resulting file instance closes the file.

package main

import (
    "fmt"
    "os"
)

func main() {
    
    
    // 只读方式打开当前目录下的main.go文件
    file, err := os.Open("./main.go")
    if err != nil {
    
    
        fmt.Println("open file failed!, err:", err)
        return
    }
    // 关闭文件
    file.Close()
}

open a file

func os.Open(name string) (*os.File, error)
fout, err := os.OpenFile("data/verse.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)

os.O_WRONLY opens the file in a write-only mode, os.O_TRUNC clears the content before the file, os.O_CREATE creates the file first if it does not exist, and 0666 sets the permission of the new file.
read file

cont := make([]byte, 10)
fin.Read(cont) //读出len(cont)个字节,返回成功读取的字节数
fin.ReadAt(cont, int64(n)) //从指定的位置开始读len(cont)个字节
fin.Seek(int64(n), 0) //重新定位。whence: 0从文件开头计算偏移量,1从当前位置计算偏移量,2到文件末尾的偏移量
reader := bufio.NewReader(fin) //读文件文件建议用bufio.Reader
for {
    
     //无限循环
    if line, err := reader.ReadString('\n'); err != nil {
    
     //指定分隔符
        if err == io.EOF {
    
    
            if len(line) > 0 {
    
     //如果最后一行没有换行符,则此时最后一行就存在line里
                fmt.Println(line)
            }
            break //已读到文件末尾
        } else {
    
    
            fmt.Printf("read file failed: %v\n", err)
        }
    } else {
    
    
        line = strings.TrimRight(line, "\n") //line里面是包含换行符的,需要去掉
        fmt.Println(line)
    }
}

write file

package main

import (
    "fmt"
    "os"
)

func main() {
    
    
    // 新建文件
    file, err := os.Create("./xxx.txt")
    if err != nil {
    
    
        fmt.Println(err)
        return
    }
    defer file.Close()
    for i := 0; i < 5; i++ {
    
    
        file.WriteString("ab\n")
        file.Write([]byte("cd\n"))
    }
}

write file

defer fout.Close() //别忘了关闭文件句柄
writer := bufio.NewWriter(fout)
writer.WriteString("明月多情应笑我")
writer.WriteString("\n") //需要手动写入换行符
writer.Flush()// 强制清空缓存,即把缓存里的内容写入磁盘

read file

You can use file.Read() and file.ReadAt() to read the file, and the error of io.EOF will be returned when the end of the file is read.

package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    
    
    // 打开文件
    file, err := os.Open("./xxx.txt")
    if err != nil {
    
    
        fmt.Println("open file err :", err)
        return
    }
    defer file.Close()
    // 定义接收文件读取的字节数组
    var buf [128]byte
    var content []byte
    for {
    
    
        n, err := file.Read(buf[:])
        if err == io.EOF {
    
    
            // 读取结束
            break
        }
        if err != nil {
    
    
            fmt.Println("read file err ", err)
            return
        }
        content = append(content, buf[:n]...)
    }
    fmt.Println(string(content))
}

copy files

package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    
    
    // 打开源文件
    srcFile, err := os.Open("./xxx.txt")
    if err != nil {
    
    
        fmt.Println(err)
        return
    }
    // 创建新文件
    dstFile, err2 := os.Create("./abc2.txt")
    if err2 != nil {
    
    
        fmt.Println(err2)
        return
    }
    // 缓冲读取
    buf := make([]byte, 1024)
    for {
    
    
        // 从源文件读数据
        n, err := srcFile.Read(buf)
        if err == io.EOF {
    
    
            fmt.Println("读取完毕")
            break
        }
        if err != nil {
    
    
            fmt.Println(err)
            break
        }
        //写出去
        dstFile.Write(buf[:n])
    }
    srcFile.Close()
    dstFile.Close()
}

bufio

  • The bufio package implements reading and writing with a buffer, which is the encapsulation of reading and writing files
  • bufio buffer write data
model meaning
os.O_WRONLY just write
os.O_CREATE Create a file
os.O_RDONLY read only
os.O_RDWR read and write
os.O_TRUNC empty
os.O_APPEND addition
  • bufio read data
package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func wr() {
    
    
    // 参数2:打开模式,所有模式d都在上面
    // 参数3是权限控制
    // w写 r读 x执行   w  2   r  4   x  1
    file, err := os.OpenFile("./xxx.txt", os.O_CREATE|os.O_WRONLY, 0666)
    if err != nil {
    
    
        return
    }
    defer file.Close()
    // 获取writer对象
    writer := bufio.NewWriter(file)
    for i := 0; i < 10; i++ {
    
    
        writer.WriteString("hello\n")
    }
    // 刷新缓冲区,强制写出
    writer.Flush()
}

func re() {
    
    
    file, err := os.Open("./xxx.txt")
    if err != nil {
    
    
        return
    }
    defer file.Close()
    reader := bufio.NewReader(file)
    for {
    
    
        line, _, err := reader.ReadLine()
        if err == io.EOF {
    
    
            break
        }
        if err != nil {
    
    
            return
        }
        fmt.Println(string(line))
    }

}

func main() {
    
    
    re()
}

ioutiltoolkit

  • toolkit write file
  • toolkit read file
package main

import (
   "fmt"
   "io/ioutil"
)

func wr() {
    
    
   err := ioutil.WriteFile("./yyy.txt", []byte("www.5lmh.com"), 0666)
   if err != nil {
    
    
      fmt.Println(err)
      return
   }
}

func re() {
    
    
   content, err := ioutil.ReadFile("./yyy.txt")
   if err != nil {
    
    
      fmt.Println(err)
      return
   }
   fmt.Println(string(content))
}

func main() {
    
    
   re()
}

example

Implement a cat command

Use the relevant knowledge of file operation to simulate the function of the cat command on the linux platform.

package main

import (
    "bufio"
    "flag"
    "fmt"
    "io"
    "os"
)

// cat命令实现
func cat(r *bufio.Reader) {
    
    
    for {
    
    
        buf, err := r.ReadBytes('\n') //注意是字符
        if err == io.EOF {
    
    
            break
        }
        fmt.Fprintf(os.Stdout, "%s", buf)
    }
}

func main() {
    
    
    flag.Parse() // 解析命令行参数
    if flag.NArg() == 0 {
    
    
        // 如果没有参数默认从标准输入读取内容
        cat(bufio.NewReader(os.Stdin))
    }
    // 依次读取每个指定文件的内容并打印到终端
    for i := 0; i < flag.NArg(); i++ {
    
    
        f, err := os.Open(flag.Arg(i))
        if err != nil {
    
    
            fmt.Fprintf(os.Stdout, "reading from %s failed, err:%v\n", flag.Arg(i), err)
            continue
        }
        cat(bufio.NewReader(f))
    }
} 

Create files/directories

os.Create(name string)//创建文件
os.Mkdir(name string, perm fs.FileMode)//创建目录
os.MkdirAll(path string, perm fs.FileMode)//增强版Mkdir,沿途的目录不存在时会一并创建
os.Rename(oldpath string, newpath string)//给文件或目录重命名,还可以实现move的功能
os.Remove(name string)//删除文件或目录,目录不为空时才能删除成功
os.RemoveAll(path string)//增强版Remove,所有子目录会递归删除

traverse directory

if fileInfos, err := ioutil.ReadDir(path); err != nil {
    
    //fileInfos是切片
	return err
} else {
    
    
    for _, fileInfo := range fileInfos {
    
    
    fmt.Println(fileInfo.Name())
    if fileInfo.IsDir() {
    
     //如果是目录,就递归子遍历
        walk(filepath.Join(path, fileInfo.Name}
    }
}

  The default log output to the console.

log.Printf("%d+%d=%d\n", 3, 4, 3+4)
log.Println("Hello Golang")
log.Fatalln("Bye, the world") //日志输出后会执行os.Exit(1)

  Specify the log output to a file.

logWriter := log.New(fout, "[BIZ_PREFIX]", log.Ldate|log.Lmicroseconds) //通过flag参数定义日志的格式,fout创建的文件,[BIZ_PREFIX]给一个日志前面的固定格式
logWriter.Println("Hello Golang")

call system command

cmd_path, err := exec.LookPath("df") //查看系统命令所在的目录,确保命令已安装
cmd := exec.Command("df", "-h") //相当于命令df -h,注意Command的每一个参数都不能包含空格
output, err := cmd.Output() //cmd.Output()运行命令并获得其输出结果
cmd = exec.Command("rm", "./data/test.log")
cmd.Run() //如果不需要获得命令的输出,直接调用cmd.Run()即可

Guess you like

Origin blog.csdn.net/m0_52896752/article/details/129795980