为了账号安全,请及时绑定邮箱和手机立即绑定

如何从 golang 中的 gzip 或纯文本阅读器读取?

如何从 golang 中的 gzip 或纯文本阅读器读取?

Go
一只斗牛犬 2021-09-13 15:25:22
我正在用 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{

   ...

}

希望有帮助。


查看完整回答
反对 回复 2021-09-13
?
智慧大石

TA贡献1946条经验 获得超3个赞

谢谢大家 - 原来 twotwotwo 和 Thundercat 是正确的,并且流在与我发布的代码无关的地方被破坏了。奇怪的是,这似乎与在仍然从请求流中读取的同时写入 http 响应有关。我仍在调查它,但似乎最初的问题被误导了。


查看完整回答
反对 回复 2021-09-13
  • 2 回答
  • 0 关注
  • 169 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信