zoukankan      html  css  js  c++  java
  • 15 文件操作与终端读取

    主要涉及的模块

    1. os
    2. bufio
    3. ioutil

    终端读取

    终端读取我们可以使用os模块,分别是:

    1. os.Stdin 标准输入
    2. os.Stdout 标准输出
    3. os.Stderr 标准错误输出

    终端读例子:

    fmt不带缓冲区 的读。

    读取的话可以使用最简单的fmt模块。代码如下所示:

    package main
    
    import (
    	"fmt"
    )
    
    var (
    	firstName, lastName, s string
    	i                      int
    	f                      float32
    	input                  = "56.12 / 5212 / Go"
    	format                 = "%f / %d / %s"
    )
    
    func main() {
    	fmt.Println("Please enter your full name: ")
    	fmt.Scanln(&firstName, &lastName) // 从终端读取
    	// fmt.Scanf("%s %s", &firstName, &lastName)
    	fmt.Printf("Hi %s %s!
    ", firstName, lastName) // Hi Chris Naegels
    	fmt.Sscanf(input, format, &f, &i, &s)          //从终端读取,且能够被格式化成其他数据类型
    	fmt.Println("From the string we read: ", f, i, s)
    }
    
    bufio带缓冲区的读

    带缓冲区的读的话,可以减少IO的压力。

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"os"
    )
    
    var inputReader *bufio.Reader
    var input string
    var err error
    
    func main() {
    	inputReader = bufio.NewReader(os.Stdin)
    	fmt.Println("Please enter some input: ")
    	input, err = inputReader.ReadString('
    ') // 也可以ReadLine
    	if err == nil {
    		fmt.Printf("The input was: %s
    ", input)
    	}
    }
    
    
    练手的例子:从终端读取一行字符串,统计英文、数字、空格以及其他字符的数量

    如何统计英文数字以及空格呢?我们可以使用ascii码的大小来比较统计,我们for循环出来的都是一个一个的字符byte,所以可以很容易的找到这个ascii,比如判断字符 a<b,go会自动转为ascii码来对比,由于b比a的ascii码更大,所以是正确的。了解原因后,我们看看下面的代码,
    代码如下:

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"os"
    )
    
    func main() {
    	reader := bufio.NewReader(os.Stdin)
    
    	var azNum int
    	var intNum int
    	var fuhaoNum int
    	var otherNum int
    	rawstring, _, _ := reader.ReadLine()
    
    	result := []rune(string(rawstring))
    	for _, key := range result {
    		//fmt.Printf("%v %T
    ", key, key)
    		switch {
    		case key >= 'a' && key <= 'z':
    			fallthrough
    		case key >= 'A' && key <= 'Z':
    			azNum++
    		case key >= '0' && key <= '9':
    			intNum++
    		case key == ' ' || key == '	':
    			fuhaoNum++
    		default:
    			otherNum++
    		}
    	}
    	fmt.Println("azNum", azNum)
    	fmt.Println("intNum", intNum)
    	fmt.Println("fuhaoNum", fuhaoNum)
    	fmt.Println("otherNum", otherNum)
    }
    
    

    文件的读写

    os.File封装所有文件相关操作,之前讲的 os.Stdin,os.Stdout, os.Stderr都是*os.File

    1. 打开一个文件进行读操作: os.Open(name string) (*File, error)
    2. 关闭一个文件:File.Close()
    文件的读

    我们接下来看看文件操作的示例,文件打开的话我们使用os.Open方法来打开

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"io"
    	"os"
    )
    
    func main() {
    
    	inputFile, err := os.Open("aaa.go")   // 打开一个文件
    	if err != nil {
    		fmt.Printf("open file err:%v
    ", err)
    		return
    	}
    
    	defer inputFile.Close()
    	inputReader := bufio.NewReader(inputFile)
    	for {
    		inputString, readerError := inputReader.ReadString('
    ')
    		if readerError == io.EOF {
    			return
    		}
    		fmt.Printf("The input was: %s", inputString)
    	}
    }
    
    
    文件的写(ioutil.WriteFile)

    文件写入我们可以使用os.OpenFile(),也可以使用ioutil.WriteFile()

    1. ioutil.ReadFile和ioutil.WriteFile 是整读整取。
      代码如下:
    // readFile_ioutil
    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    	"os"
    )
    
    func main() {
    	inputFile := "d:/111.txt"
    	outputFile := "d:/112.txt"
    	buf, err := ioutil.ReadFile(inputFile)
    	if err != nil {
    		fmt.Fprintf(os.Stderr, "File error:%s", err)
    	}
    	fmt.Printf("%s
    ", string(buf))
    	err = ioutil.WriteFile(outputFile, buf, 0644)
    	if err != nil {
    		panic(err.Error())
    	}
    }
    
    

    文件的写(bufio.NewWriter与os.OpenFile)

    • 代码:os.OpenFile(“output.dat”, os.O_WRONLY|os.O_CREATE, 0666)
    • 第二个参数:文件打开模式:
    1. os.O_WRONLY:只写
    2. os.O_CREATE:创建文件
    3. os.O_RDONLY:只读
    4. os.O_RDWR:读写
    5. os.O_TRUNC :清空
    • 第三个参数:权限控制:
    1. r ——> 004
    2. w——> 002
    3. x——> 001

    我们使用os.OpenFile来打开一个文件,os.O_WRONLY|os.O_CREATE 表示是如果没有那么就创建新文件,只读写该文件,权限模式为0666,
    完整代码如下:

    // WriteToFile
    package main
    
    import (
    	"bufio"
    	"os"
    	"fmt"
    )
    
    func main() {
    	outputFile,err := os.OpenFile("output.txt",os.O_WRONLY|os.O_CREATE,0666)
    	if err != nil {
    		fmt.Printf("an error happend with fil crea
    ")
    		return
    	}
    	defer outputFile.Close()
    	outputWriter := bufio.NewWriter(outputFile)
    	outputString := "hello world!
    "
    	for i:=0;i<10;i++ {
    		outputWriter.WriteString(outputString)
    	}
    	outputFile.Flush()
    }
    

    利用读写来拷贝文件

    我们这次实现拷贝文件通过边读边写的方式来实现文件的拷贝,主要是使用os.OpenFile和os.Open来时实现,代码如下:

    // copyFile
    package main
    
    import (
    	"fmt"
    	"io"
    	"os"
    )
    
    func copyFile(dstName, srcName string) (written int64, err error) {
    	src, err := os.Open(srcName)
    	if err != nil {
    		fmt.Println("happend a error when opening", err)
    	}
    	defer src.Close()
    	dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
    	if err != nil {
    		fmt.Println("happend a error when opening", err)
    	}
    	defer dst.Close()
    	return io.Copy(dst, src)
    }
    
    func main() {
    	copyFile("test.gz", "test.log.gz")
    }
    
    
  • 相关阅读:
    Leetcode 16.25 LRU缓存 哈希表与双向链表的组合
    Leetcode437 路径总和 III 双递归与前缀和
    leetcode 0404 二叉树检查平衡性 DFS
    Leetcode 1219 黄金矿工 暴力回溯
    Leetcode1218 最长定差子序列 哈希表优化DP
    Leetcode 91 解码方法
    Leetcode 129 求根到叶子节点数字之和 DFS优化
    Leetcode 125 验证回文串 双指针
    Docker安装Mysql记录
    vmware虚拟机---Liunx配置静态IP
  • 原文地址:https://www.cnblogs.com/liaojiafa/p/7213799.html
Copyright © 2011-2022 走看看