我正在用 golang 編寫一個小型 webapp,它涉及解析用戶上傳的文件。我想自動檢測文件是否被 gzip 壓縮并適當地創建閱讀器/掃描儀。一個轉折是我無法將整個文件讀入內存,我只能單獨對流進行操作。這是我所擁有的:func scannerFromFile(reader io.Reader) (*bufio.Scanner, error) {var scanner *bufio.Scanner//create a bufio.Reader so we can 'peek' at the first few bytesbReader := bufio.NewReader(reader)testBytes, err := bReader.Peek(64) //read a few bytes without consumingif err != nil { return nil, err}//Detect if the content is gzippedcontentType := http.DetectContentType(testBytes)//If we detect gzip, then make a gzip reader, then wrap it in a scannerif strings.Contains(contentType, "x-gzip") { gzipReader, err := gzip.NewReader(bReader) if (err != nil) { return nil, err } scanner = bufio.NewScanner(gzipReader)} else { //Not gzipped, just make a scanner based on the reader scanner = bufio.NewScanner(bReader)}return scanner, nil}這適用于純文本,但對于 gzipped 數據,它會錯誤地膨脹,并且在幾 kb 之后,我不可避免地會出現亂碼。有沒有更簡單的方法?任何想法為什么在幾千行之后它不正確地解壓縮?
2 回答

陪伴而非守候
TA貢獻1757條經驗 獲得超8個贊
您可以通過檢查前 2 個字節是否等于0x1f8b(我在這里找到了該信息)來檢測文件是否被 gzip 。
在評論中有人提到你應該分別檢查這些字節,所以第一個是0x1f,第二個是0x8b.
testBytes, err := bReader.Peek(2) //read 2 bytes
....
if testBytes[0] == 31 && testBytes[1] == 139 {
//gzip
}else{
...
}
希望有幫助。

智慧大石
TA貢獻1946條經驗 獲得超3個贊
謝謝大家 - 原來 twotwotwo 和 Thundercat 是正確的,并且流在與我發布的代碼無關的地方被破壞了。奇怪的是,這似乎與在仍然從請求流中讀取的同時寫入 http 響應有關。我仍在調查它,但似乎最初的問題被誤導了。
- 2 回答
- 0 關注
- 197 瀏覽
添加回答
舉報
0/150
提交
取消