Go 讀寫數(shù)據(jù)

用戶輸入

fmt.Scanxx

  • fmt.Scanln
var s1,s2 string
fmt.Scanln(&s1,&s2)

以上是讀取一行,以空格分隔,直到遇到非空字符。所以如果代碼是這樣的:

var s1,s2 string
fmt.Scanln(&s1)
fmt.Scanln(&s2)
fmt.Printnln(s1,s2)

而輸入了abcd efg那么輸出將會是abcd fg,因為第二個單詞的第一個字符被當作換行處理。但是如果輸入abcd\n,那么第二個字符串將會讀取不到,因為是按行來讀取的,遇到換行直接就讀完了。

  • fmt.Scanf()

fmt.Scanf和C語言中的scanf用法一樣:fmt.Scanf("%s%s",&s1,&s2)

  • fmt.Scan()

fmt.Scan()不處理換行符,直到傳入的參數(shù)都讀取完畢。如fmt.Scan(&s1,&2),讀取的兩個字符串之間可以有換行符。

fmt.Sscanxxx

遇到S開頭的scan函數(shù),其處理的都是字符串,不會處理用戶輸入。
如:

input := "abcd efg"
fmt.Sscan(input,&s1,&s2)
fmt.Sscanln(input,&s1,&s2)
fmt.Sscanf(input,"%s%s",&s1,&s2)

bufio

利用bufio也可以讀取數(shù)據(jù):

  • bufio.NewScanner
    inputScanner := bufio.NewScanner(os.Stdin)
    inputScanner.Scan()
    fmt.Println(inputScanner.Text())

其中inputScanner.Scan()會將讀取的一行數(shù)據(jù)保存在內部的緩沖區(qū)中,使用inputScanner.Text()可以將其讀取出來,注意Scan不會將換行符讀進去,并且類似\n這種字符,他又不會去轉義。

  • bufio.NewReader
    inputReader := bufio.NewReader(os.Stdin)
    input,err := inputReader.ReadString(',')

但是注意,這個函數(shù)和inputScanner不一樣,這個是直接返回讀取的數(shù)據(jù)以及error,其中參數(shù)表示,讀取到對應的字符就停止,并且返回的數(shù)據(jù)包含該字符。所以如果輸入是abcd,,則input的值就是abcd,
不止ReadString可以讀取,ReadBytes也可以讀取,不過ReadBytes返回的是byte類型的切片。byte類型的切片又和string可以互轉,所以基本上是一樣的。

文件讀寫

os.Open和bufio

os.Open("input.txt")用于打開一個文件,文件類型一般是os.*File類型,而os.Stdin也是os.*File類型,所以對于bufio.NewScanner()bufio.NewReader也可以傳入一個文件。所以文件讀取最簡單的思路就是通過os.Openbufio包實現(xiàn):

    file,err := os.Open("test.go")
    if err != nil{
        fmt.Println("讀取文件失敗")
    }
    inputScan := bufio.NewScanner(file)
    for inputScan.Scan() {
        fmt.Println(inputScan.Text())
    }

當然也可以通過bufio.NewReader(file)來實現(xiàn),但是注意,這種方法實現(xiàn)的需要判斷err,如果讀取到文件結尾,將會返回io.EOF,所以讀取整個文件的方式是:

    file,err := os.Open("test.go")
    if err != nil{
        fmt.Println("讀取文件失敗")
    }
    inputReader := bufio.NewReader(file)
    for {
        line,err := inputReader.ReadString('\n')
        fmt.Printf("%s",line)
        if err == io.EOF{
            return
        }
    }

注意返回io.EOF的時候,line變量里也會有值。

ioutil

利用ioutil.ReadXxx的函數(shù)可以讀取文件內容或用戶輸入,如:

    file,err := os.Open("test.go")
    defer file.Close()
    if err != nil{
        fmt.Println("讀取錯誤")
    }
    bytes,err := ioutil.ReadAll(file)
    if err != nil{
        fmt.Println("讀取又錯誤")
    }
    fmt.Println(string(bytes))

ioutil.ReadAll傳入的是io.Reader,所以對于os.Open,其剛好返回io.Reader,所以是可以的。
同樣也可以使用ioutil.ReadFile方法,該方法其實就是對上述方法的封裝:

    bytes,err := ioutil.ReadFile("test.go")
    if err != nil{
        fmt.Println("讀取錯誤")
    }
    fmt.Println(string(bytes))

緩沖讀取

    f,err := os.Open("test.go")
    if err != nil{
        fmt.Println("錯誤")
    }
    fefer f.Close()
    inputReader := bufio.NewReader(f)
    buf := make([]byte,1024)
    n,err := inputReader.Read(buf)
    for n!=0 && err ==nil{
        fmt.Println(string(buf))
        n,err = inputReader.Read(buf)
    }

其中inpuReader.Read方法傳入的就是緩沖的參數(shù),該函數(shù)返回的是n表示讀入的字節(jié)個數(shù)。注意,一定要融會貫通,這樣讀取的方式不僅僅對文件使用,同樣對屏幕輸入適用。

fmt.Fscanxxx

同樣fmt里包含F(xiàn)開頭的一些讀取函數(shù),與fmt.Sscanln``fmt.Sscan``fmt.Sscanf是類似的,不過第一個參數(shù)從傳入字符串,變成了傳入文件。

文件寫入

最簡單的是通過fmt.Fprintf將一個字符串寫入:fmt.Fprintf(file,"some data\n")fmt.Fprintln(file,"some data")

    f,_ := os.Open("test.go")
    _,err := fmt.Fprintln(f,"someData")
    fmt.Println(err)

這種方式要注意權限,如果沒有權限就會寫入不成功
另一種方法是通過os.OpenFile來打開文件,并且賦予打開的方式,如:

    outputFile,err := os.OpenFile("test.go",os.O_WRONLY|os.O_CREATE,0666)
    if err != nil{
        fmt.Println("錯誤")
    }
    defer outputFile.Close()
    outputFile.WriteString("哈哈哈,我終于寫進來了")

需要注意的是,第二個參數(shù)是打開的模式,可以有只讀模式,以及追加模式等,一般用的模式有:

const (
    O_RDONLY int = syscall.O_RDONLY // open the file read-only.
    O_WRONLY int = syscall.O_WRONLY // open the file write-only.
    O_RDWR   int = syscall.O_RDWR   // open the file read-write.
    O_APPEND int = syscall.O_APPEND // append data to the file when writing.
    O_CREATE int = syscall.O_CREAT  // create a new file if none exists.
    O_EXCL   int = syscall.O_EXCL   // used with O_CREATE, file must not exist
    O_SYNC   int = syscall.O_SYNC   // open for synchronous I/O.
    O_TRUNC  int = syscall.O_TRUNC  // if possible, truncate file when opened.
)

在寫入文件的時候,第三個參數(shù)必須是0666,而對于讀的時候可以忽略。
如果寫入的內容過多,可以通過bufio來創(chuàng)建一個有緩沖的寫入器:

bufio.NewWriter(outputFile)

文件拷貝

io.Copy(target,source)
但是注意source文件可以通過os.Open讀取,而target文件必須使用os.OpenFile來讀取,并賦予os.O_WRONLY標志或者其他可寫標志。

命令行讀取

命令行讀取可以通過os.Args來獲取命令的參數(shù),同樣可以通過flag包來設置參數(shù)。
比如輸入:./goTest hahaha lalal那么os.Args中存放的就是[./goTest,hahaha,lalal],可以通過os.Args[1]這種方式來取出。

但是如果我想要./goTest -name Mike這種方式來取數(shù)據(jù)怎么辦呢,方法就是通過flag包。
比如:

    name := flag.String("name","","輸入你的名字~")
    flag.Parse()
    fmt.Println(*name)

注意name是一個指針類型,通過flag.Parse()方法可以解析命令行參數(shù),通過*name將輸入取出,flag.String的第一個參數(shù)表示命令行中的參數(shù)名,如輸入./goTest -name "hahah",其中-name就是對應第一個參數(shù),第二個參數(shù)是name的默認值,如果沒有輸入,name的值就是這個默認值,第三個參數(shù)是說明,一般只有在help中出現(xiàn)。

當然不僅僅有flag.String還有flag.Bool等方法。
falg.StringVarflag.String一樣,只不過flag.StringVar沒有返回值,而是將name指針傳給了該方法:flag.StringVar(&name,"name","","輸入你的名字~")

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評論 19 139
  • fmt格式化字符串 格式:%[旗標][寬度][.精度][arg索引]動詞旗標有以下幾種:+: 對于數(shù)值類型總是輸出...
    皮皮v閱讀 1,223評論 0 3
  • 《ilua》速成開發(fā)手冊3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 1...
    葉染柒丶閱讀 11,518評論 0 11
  • 《ijs》速成開發(fā)手冊3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 10...
    葉染柒丶閱讀 5,646評論 0 7
  • Android Testing support Library 提供了一個強大的Android 應用測試框架。 l...
    HanlyJiang閱讀 1,749評論 0 2

友情鏈接更多精彩內容