国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 專題 > 區塊鏈 > 正文

區塊鏈開發中Go語言之IO操作

2020-02-25 19:26:52
字體:
來源:轉載
供稿:網友

這篇文章是對區塊鏈開發中Go語言之IO操作做一個梳理,每一個的地方,每一種的知識,每一種事物,都是從陌生到熟悉。在這個過程里面,或許能開闊眼界,增長見識,體驗樂趣,下面我們就一起來看看吧。

io,最基本的io

Reader

type Reader interface {    Read(p []byte) (n int, err error)}

實現了Reader接口的都可以用read方法,將數據讀入到p字節數組,n表示讀取了幾個字節,err返回錯誤。 如果讀到了文件尾EOF,則err返回EOF。
注意,當文件最后一小段已經無法填滿p這個字節數組時,不會產生EOF的錯誤,只會在下一次讀取時產生n=0,err=io.EOF的錯誤

舉例

func main() {    file, _ := os.Open("main.go")    var a [128]byte    count:=0    for {        n, err := file.Read(a[:])        count+=1        if err != nil {            if err == io.EOF {                break            } else {                os.Exit(1)            }        }        fmt.Printf("%s/n", a[:n])    }    fmt.Printf("%d/n", count)}

Writer

type Writer interface {    Write(p []byte) (n int, err error)}

Write 將 len(p) 個字節從 p 中寫入到基本數據流中。它返回從 p 中被寫入的字節數 n(0 常見錯誤原因有磁盤滿了

ReaderAt 和 WriterAt 接口

和Reader,Writer類似,但是需要自己調控偏移量。
注意:接近文件尾巴時,當n小于數組大小時也觸發了err.EOF,需要自行把最后n小于數組大小的這點數據處理一下。

舉例:

func main() {    file, _ := os.Open("main.go")    var a [128]byte    count := 0    var pos int64 = 0    for {        n, err := file.ReadAt(a[:], pos)        count += 1        pos += int64(n)        if err != nil {            if err == io.EOF {                fmt.Printf("%s", a[:n]) //區別在這里                break            } else {                os.Exit(1)            }        }        fmt.Printf("%s", a[:n])    }    fmt.Println()    fmt.Printf("%d", count)}

ReaderFrom 和 WriterTo 接口

一次性讀完直到EOF,或者寫入全部數據

Seeker 接口

type Seeker interface {    Seek(offset int64, whence int) (ret int64, err error)}

用來設置偏移量,也就是從哪開始讀,offset由whence解釋。

  • 0 表示相對于文件的起始處
  • 1 表示相對于當前的偏移,
  • 2 表示相對于其結尾處。

ByteReader 和 ByteWriter

讀或寫一個字節

ioutil — 方便的IO操作函數集

ReadAll

一次性讀取數據

ReadDir

讀取目錄并返回排好序的文件和子目錄名

ReadFile 和 WriteFile

func WriteFile(filename string, data []byte, perm os.FileMode) error

這里特別注意的是寫文件的權限問題,perm的數值,和linux規則一致 四位(777):

模式

數字

rwx

7

rw-

6

r-x

5

r--

4

-wx

3

-w-

2

--x

1

---

0

組合如0666,表示rw-rw-rw-

?

bufio,帶緩存的io

是io庫的包裝,提供帶緩存的方法

ReadSlice、ReadBytes、ReadString 和 ReadLine 方法

后三個方法最終都是調用ReadSlice來實現的

ReadSlice
func (b *Reader) ReadSlice(delim byte) (line []byte, err error)

示例:

reader := bufio.NewReader(strings.NewReader("http://studygolang.com. /nIt is the home of gophers"))line, _ := reader.ReadSlice('/n')fmt.Printf("the line:%s/n", line)// 這里可以換上任意的 bufio 的 Read/Write 操作n, _ := reader.ReadSlice('/n')fmt.Printf("the line:%s/n", line)fmt.Println(string(n))

輸出:

the line:http://studygolang.com. the line:It is the home of gophersIt is the home of gophers

注意ReadSlice每次返回的line是指向同一個緩存數組,因此ReadSlice的實現是反復覆蓋重寫緩存數組。

如果ReadSlice在找到分界符前

  1. 緩存數組就滿了,則返回bufio.ErrBufferFull
  2. 遇到EOF了,則返回ErrEOF
ReadBytes
func (b *Reader) ReadBytes(delim byte) (line []byte, err error)

返回的byte是copy的一份數組

從以下實驗可看出來

reader := bufio.NewReader(strings.NewReader("http://studygolang.com. /nIt is the home of gophers"))line, _ := reader.ReadBytes('/n')fmt.Printf("the line:%s/n", line)// 這里可以換上任意的 bufio 的 Read/Write 操作n, _ := reader.ReadBytes('/n')fmt.Printf("the line:%s/n", line)fmt.Println(string(n))

輸出

the line:http://studygolang.com. the line:http://studygolang.com. It is the home of gophers
ReadString

是對ReadBytes的封裝,將返回的line轉換成string

ReadLine
func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)

這里要說的是isPrefix,用于讀取的一行超過了緩存大小,則isPrefix為true,下次還讀這行余下的部分,直到讀完這行才isPrefix返回false

ReadLine返回的文本不會包含行結尾("/r/n"或者"/n")

Peek

該方法只是“窺探”一下Reader中沒有讀取的n個字節。好比棧數據結構中的取棧頂元素,但不出棧。

func (b *Reader) Peek(n int) ([]byte, error)

同上面介紹的ReadSlice一樣,返回的[]byte只是buffer中的引用。所以在并發的時候有可能就被別人給改了

Scanner 類型和方法

用于方便的按token讀取數據,token的分詞規則用SplitFunc定義。默認按行分詞,會去掉末尾換行符。 了解Scanner前要先了解SplitFunc

SplitFunc
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

SplitFunc 定義了 用于對輸入進行分詞的 split 函數的簽名。

參數

  1. data 是還未處理的數據,
  2. atEOF 標識 Reader是否還有更多數據(是否到了EOF)。

返回值

  1. advance data里下一個token開始位置
  2. token 表示當前token的結果數據
  3. err 則代表可能的錯誤。

舉例

func main() {    // Comma-separated list; last entry is empty.    const input = "1,2,3,4,"    scanner := bufio.NewScanner(strings.NewReader(input))    // Define a split function that separates on commas.    onComma := func(data []byte, atEOF bool) (advance int, token []byte, err error) {        for i := 0; i 

輸出

"1" "2" "3" "4" "5"

你也可以用系統定義好的幾個分割token的方法。


  1. ScanBytes 返回單個字節作為一個 token。
    ?

  2. ScanRunes 返回單個 UTF-8 編碼的 rune 作為一個 token。返回的 rune 序列(token)和 range string類型 返回的序列是等價的,也就是說,對于無效的 UTF-8 編碼會解釋為 U+FFFD = "/xef/xbf/xbd"。
    ?

  3. ScanWords 返回通過“空格”分詞的單詞。如:study golang,調用會返回study。注意,這里的“空格”是 unicode.IsSpace(),即包括:'/t', '/n', '/v', '/f', '/r', ' ', U+0085 (NEL), U+00A0 (NBSP)。
    ?

  4. ScanLines 返回一行文本,不包括行尾的換行符。這里的換行包括了Windows下的"/r/n"和Unix下的"/n"。
    ?
Scanner 的使用方法
  1. NewScanner
  2. Split設置分割token的方法
  3. 循環scanner.Scan()
  4. 在循環里用scanner.Text()取token 示例
const input = "This is The Golang Standard Library./nWelcome you!"scanner := bufio.NewScanner(strings.NewReader(input))scanner.Split(bufio.ScanWords)count := 0for scanner.Scan() {    count++}if err := scanner.Err(); err != nil {    fmt.Fprintln(os.Stderr, "reading input:", err)}fmt.Println(count)

Writer

帶緩存的writer,記得在最終的寫入操作執行完后flush一下,確保全部緩存都真正寫入,如果大家想了解更多精彩內容,盡在https://js.Vevb.com。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 邢台市| 卫辉市| 建湖县| 竹溪县| 全州县| 安溪县| 临高县| 南城县| 东兰县| 轮台县| 冷水江市| 汉寿县| 体育| 塔河县| 三门峡市| 镇远县| 临洮县| 赤水市| 固阳县| 黑山县| 蒲城县| 怀集县| 甘泉县| 和硕县| 襄汾县| 定南县| 甘德县| 济宁市| 金秀| 棋牌| 江都市| 闻喜县| 突泉县| 合作市| 凤山县| 梁平县| 蓬安县| 和静县| 凤山县| 建始县| 邻水|