天天看點

Go基礎--終端操作和檔案操作

終端操作

操作終端相關的檔案句柄常量

os.Stdin:标準輸入

os.Stdout:标準輸出

os.Stderr:标準錯誤輸出

關于終端操作的代碼例子:

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)
    fmt.Sscanf(input,format,&f,&i,&s)
    fmt.Println("From the string we read:",f,i,s)

}      

關于帶緩沖區的讀寫

這裡需要用到一個包:bufio

下面是代碼例子:

package main

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

var inputReader *bufio.Reader
var input string
var err error


func main(){
    inputReader = bufio.NewReader(os.Stdin)
    fmt.Println("please enter some input:")
    // 下面這個表示我們讀取一行,最後是以\n 為分割的,\n表示換行
    input,err = inputReader.ReadString('\n')
    if err != nil{
        fmt.Println(err)
        return
    }
    fmt.Printf("the input was:%s\n",input)
}      

練習終端操作

從終端讀取一行字元串,統計英文,數字,空格以及其他字元的數量

代碼實作:

package main

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

func judgeCount(str string){
    var countNum, countLetter, countSpace, countOther int
    for _, v := range str {
        if v >= 'a' && v <= 'z' || v >= 'A' && v <= 'Z' {
            countLetter++
        } else if v >= '0' && v <= '9' {
            countNum++
        } else if v == ' ' {
            countSpace++
        } else {
            countOther++
        }
    }
    fmt.Println("英文字母的個數:", countLetter)
    fmt.Println("數字的個數:", countNum)
    fmt.Println("空格的個數:", countSpace)
    // 關于其他字元這裡進行減一是因為這裡多算了一個換行符\n
    fmt.Println("其他字元的個數:", countOther-1)

}

func main(){
    fmt.Println("請輸入一行字元串:")
    var inputReader *bufio.Reader
    inputReader = bufio.NewReader(os.Stdin)
    str,err := inputReader.ReadString('\n')
    if err!=nil{
        fmt.Println("輸入錯誤,錯誤為:",err)
        return
    }
    judgeCount(str)
}      

關于檔案讀寫

os.File封裝所有檔案相關的操作

打開一個檔案進行讀操作:os.Open(name string)(*File,error)

關閉一個檔案:File.Close()

關于檔案操作的一個簡單例子:

package main

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

func main(){
    file,err:= os.Open("/Users/zhaofan/go_project/src/go_dev/07/ex13/main.go")
    if err!= nil{
        fmt.Println("open file is err:",err)
        return
    }
    //這裡切記在打開檔案的時候跟上defer 關閉這個檔案,防止最後忘記關閉
    defer file.Close()
    inputReader := bufio.NewReader(file)
    for {
        inputString,readError:= inputReader.ReadString('\n')
        // 這裡readError == io.EOF表示已經讀到檔案末尾
        if readError ==io.EOF{
            return
        }
        // 下面會把每行的内容進行列印
        fmt.Printf("the input is:%s",inputString)
    }

}      

上面例子中關于讀檔案是一行一行的讀的,下面我們也可以一次性讀完整的檔案,但是切記如果檔案過大,這種方法不适用,這裡用到是io/ioutil包

package main

import (
    "io/ioutil"
    "fmt"
)

func main(){
    buf,err := ioutil.ReadFile("/Users/zhaofan/go_project/src/go_dev/07/ex13/main.go")
    if err != nil{
        fmt.Println("read file is err:",err)
        return
    }
    fmt.Printf("%s\n",string(buf))

}      

關于讀取壓縮檔案的例子,這裡用到的是compress/gzip包

package main

import (
    "os"
    "fmt"
    "compress/gzip"
    "bufio"
    "io"
)

func main(){
    file,err := os.Open("/Users/zhaofan/go_project/src/go_dev/07/ex6/ggg.gz")
    if err != nil{
        fmt.Println("open file err:",err)
        return
    }
    defer file.Close()

    reader,err :=gzip.NewReader(file)
    if err != nil{
        fmt.Println("gzip err:",err)
        return
    }
    bufReader := bufio.NewReader(reader)
    for{
        line,err := bufReader.ReadString('\n')
        if err != nil{
            if err == io.EOF{
                break
            }
            fmt.Println("read file err",err)
            break
        }
        fmt.Printf("%s",line)
    }

}      

關于檔案的寫入

os.OpenFile("filename",os.O_WRONLY|os.O_CREATE,066)

第一個參數是檔案名

第二個參數是檔案的打開模式:

os.O_WRONLY:隻寫

os.O_CREATE:建立檔案

os.O_RDONLY:隻讀

os.O_RDWR:讀寫

os.O_TRUNC:清空

第三個參數:權限控制

r-->4

w-->2

x-->1

這裡和linux的是一樣的

關于寫入檔案的一個例子,這裡寫了兩種方法一種是直接writestring方法,一種是通過bufio的方式:

package main

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

func testWriteFile(){
    file,err:= os.OpenFile("mylog.txt",os.O_WRONLY|os.O_CREATE,0666)
    if err!= nil{
        fmt.Println("open file failed:",err)
        return
    }
    defer file.Close()
    for i:=0;i<10;i++{
        file.WriteString(fmt.Sprintf("go web 開發\n"))
    }

}

func testWriteBuf(){
    file,err:= os.OpenFile("mylog.txt",os.O_WRONLY|os.O_CREATE,0666)
    if err!= nil{
        fmt.Println("open file failed:",err)
        return
    }
    defer file.Close()

    bufioWrite := bufio.NewWriter(file)
    for i:=0;i<10;i++{
        bufioWrite.WriteString("hello\n")
    }
    bufioWrite.Flush()
}

func main(){
    //testWriteFile()
    testWriteBuf()
}      

關于拷貝檔案的例子:

package main

import (
    "os"
    "io"
)

func CopyFile()(writen int64,err error){
    src,err:=os.Open("mylog.txt")
    if err!= nil{
        return
    }
    defer src.Close()
    dst,err := os.OpenFile("dst.txt",os.O_WRONLY|os.O_CREATE,0644)
    if err!=nil{
        return
    }
    defer dst.Close()
    return io.Copy(dst,src)
}

func main(){
    CopyFile()
}      

關于擷取指令行參數

os.Args是一個string的切片,用來存儲所有指令行的參數

但是通過這種方式擷取參數有點笨拙,并且需要做很多的判斷,我們可以通過go裡面的flag包來做,代碼例子如下:

package main

import (
    "fmt"
    "flag"
)

var(
    conf string
    level int
)

func init()  {
    flag.StringVar(&conf,"c","/home/user/zhaofan","請指定配置檔案路徑")
    flag.IntVar(&level,"l",8,"請指定日志級别")
    flag.Parse() //這個非常重要不能忘記寫
}

func main()  {
    //for _,val := range os.Args{
    //  fmt.Println(val)
    //}

    fmt.Printf("conf is :%s\n",conf)
    fmt.Printf("level is :%d\n",level)
}      

上面的例子設定了預設參數,如果我們想自定義參數在運作的時候添加 -c=内容 -l=内容 ,就可以用我們通過指令行參數傳入的值進行處理

所有的努力都值得期許,每一份夢想都應該灌溉!