golang strings.NewReader


為什么說strings.Reader類型的值可以高效地讀取字符串

與strings.Builder類型恰恰相反,strings.Reader類型是為了高效讀取字符串而存在的。后者的高效主要體現在它對字符串的讀取機制上,它封裝了很多用於在string值上讀取內容的最佳實踐。

strings.Reader類型的值(以下簡稱Reader值)可以讓我們很方便地讀取一個字符串中的內容。在讀取的過程中,Reader值會保存已讀取的字節的計數(以下簡稱已讀計數)。

已讀計數也代表着下一次讀取的起始索引位置。Reader值正是依靠這樣一個計數,以及針對字符串值的切片表達式,從而實現快速讀取。

此外,這個已讀計數也是讀取回退和位置設定時的重要依據。雖然它屬於Reader值的內部結構,但我們還是可以通過該值的Len方法和Size把它計算出來的

Reader值擁有的大部分用於讀取的方法都會及時地更新已讀計數。比如,ReadByte方法會在讀取成功后將這個計數的值加1。

又比如,ReadRune方法在讀取成功之后,會把被讀取的字符所占用的字節數作為計數的增量。

不過,ReadAt方法算是一個例外。它既不會依據已讀計數進行讀取,也不會在讀取后更新它。正因為如此,這個方法可以自由地讀取其所屬的Reader值中的任何內容。

// 示例1。
    reader1 := strings.NewReader(
        "中文的的的SimpleNewReader returns a new Reader reading from s. " +
            "It is similar to bytes.NewBufferString but more efficient and read-only. ")
%d\n",reader1.Size()-int64(reader1.Len()))
    fmt.Printf("len:%d\n",reader1.Len()) //原始字符串長度是141
    by:= make([]byte,20)
    reader1.ReadAt(by,2) //這個方法不做計數也就是原值不變也就是len長度還是原始長度

    buf1 := make([]byte, 3) //原值偏移量+3 len長度要-3
     reader1.Read(buf1)
    fmt.Printf("len:%d value:%s\n",reader1.Len(),string(buf1))

打印結果為

len:141
len:138 value:中 

除此之外,Reader值的Seek方法也會更新該值的已讀計數。實際上,這個Seek方法的主要作用正是設定下一次讀取的起始索引位置

offset2 := int64(17)
expectedIndex := reader1.Size() - int64(reader1.Len()) + offset2
fmt.Printf("Seek with offset %d and whence %d ...\n", offset2, io.SeekCurrent)
readingIndex, _ := reader1.Seek(offset2, io.SeekCurrent)
fmt.Printf("The reading index in reader: %d (returned by Seek)\n", readingIndex)
fmt.Printf("The reading index in reader: %d (computed by me)\n", expectedIndex)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM