[英]Reading files with a BOM in Go
我需要讀取可能包含或不包含字節順序標記的 Unicode 文件。 我當然可以自己檢查文件的前幾個字節,如果找到 BOM,則丟棄 BOM。 但在我這樣做之前,是否有任何標准方法可以做到這一點,無論是在核心庫中還是在第三方中?
沒有標准的方法,IIRC(標准庫真的是一個錯誤的層來實現這種簽入)所以這里有兩個你可以如何自己處理它的例子。
一種是在數據流上方使用緩沖讀取器:
import (
"bufio"
"os"
"log"
)
func main() {
fd, err := os.Open("filename")
if err != nil {
log.Fatal(err)
}
defer closeOrDie(fd)
br := bufio.NewReader(fd)
r, _, err := br.ReadRune()
if err != nil {
log.Fatal(err)
}
if r != '\uFEFF' {
br.UnreadRune() // Not a BOM -- put the rune back
}
// Now work with br as you would do with fd
// ...
}
另一種適用於實現io.Seeker
接口的對象的io.Seeker
是讀取前三個字節,如果它們不是 BOM,則io.Seek()
回到開頭,例如:
import (
"os"
"log"
)
func main() {
fd, err := os.Open("filename")
if err != nil {
log.Fatal(err)
}
defer closeOrDie(fd)
bom := [3]byte
_, err = io.ReadFull(fd, bom[:])
if err != nil {
log.Fatal(err)
}
if bom[0] != 0xef || bom[1] != 0xbb || bom[2] != 0xbf {
_, err = fd.Seek(0, 0) // Not a BOM -- seek back to the beginning
if err != nil {
log.Fatal(err)
}
}
// The next read operation on fd will read real data
// ...
}
這是可能的,因為*os.File
實例( os.Open()
返回的內容)支持搜索並因此實現io.Seeker
。 請注意,對於 HTTP 響應的Body
閱讀器而言,情況並非如此,因為您無法“倒帶”它。 bufio.Buffer
通過執行一些緩沖(顯然)來解決不可搜索流的這個特性——這就是讓你在它上面使用UnreadRune()
的原因。
請注意,這兩個示例都假設我們正在處理的文件是用 UTF-8 編碼的。 如果您需要處理其他(或未知)編碼,事情會變得更加復雜。
在 Go 核心包中沒有這樣做的標准方法。 遵循 Unicode 標准。
您可以使用utfbom包。 它包裝io.Reader
,根據需要檢測並丟棄 BOM。 它還可以返回 BOM 檢測到的編碼。
我以為我會在這里添加到字符串中剝離字節順序標記序列的方式-而不是直接字節亂搞(如上圖所示)。
package main
import (
"fmt"
"strings"
)
func main() {
s := "\uFEFF is a string that starts with a Byte Order Mark"
fmt.Printf("before: '%v' (len=%v)\n", s, len(s))
ByteOrderMarkAsString := string('\uFEFF')
if strings.HasPrefix(s, ByteOrderMarkAsString) {
fmt.Printf("Found leading Byte Order Mark sequence!\n")
s = strings.TrimPrefix(s, ByteOrderMarkAsString)
}
fmt.Printf("after: '%v' (len=%v)\n", s, len(s))
}
其他“字符串”函數也應該工作。
這是打印出來的:
before: ' is a string that starts with a Byte Order Mark (len=50)'
Found leading Byte Order Mark sequence!
after: ' is a string that starts with a Byte Order Mark (len=47)'
干杯!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.