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!\n", 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('\n') // 也可以ReadLine
	if err == nil {
		fmt.Printf("The input was: %s\n", 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\n", key, key)
		switch {
		case key >= 'a' && key <= 'z':
			fallthrough
		case key >= 'A' && key <= 'Z':
			azNum++
		case key >= '0' && key <= '9':
			intNum++
		case key == ' ' || key == '\t':
			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\n", err)
		return
	}

	defer inputFile.Close()
	inputReader := bufio.NewReader(inputFile)
	for {
		inputString, readerError := inputReader.ReadString('\n')
		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\n", 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\n")
		return
	}
	defer outputFile.Close()
	outputWriter := bufio.NewWriter(outputFile)
	outputString := "hello world!\n"
	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")
}

posted @ 2017-07-20 18:35  温柔易淡  阅读(872)  评论(0编辑  收藏  举报