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")
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值