1. 程式人生 > >Go基礎--終端操作和檔案操作

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=內容 ,就可以用我們通過命令列引數傳入的值進行處理