【发布时间】:2015-02-03 22:28:39
【问题描述】:
我正在用 golang 编写一个小型 webapp,它涉及解析用户上传的文件。我想自动检测文件是否被压缩并适当地创建阅读器/扫描仪。一个转折是我无法将整个文件读入内存,我只能单独对流进行操作。这是我得到的:
func scannerFromFile(reader io.Reader) (*bufio.Scanner, error) {
var scanner *bufio.Scanner
//create a bufio.Reader so we can 'peek' at the first few bytes
bReader := bufio.NewReader(reader)
testBytes, err := bReader.Peek(64) //read a few bytes without consuming
if err != nil {
return nil, err
}
//Detect if the content is gzipped
contentType := http.DetectContentType(testBytes)
//If we detect gzip, then make a gzip reader, then wrap it in a scanner
if 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
}
这适用于纯文本,但对于 gzip 压缩的数据,它会错误地膨胀,并且在几 kb 之后,我不可避免地会得到乱码。有没有更简单的方法?任何想法为什么在几千行之后它会错误地解压缩?
【问题讨论】:
-
让我怀疑这段代码之外的内容是否有问题——来自 gzip 阅读器的乱码文本绝对是我没想到的。 (编辑:哎呀,“不要”很重要。:))
-
代码对我来说看起来是正确的。我推荐
contentType == "application/x-gzip"而不是strings.Contains。 -
如果压缩流本身已损坏,我希望您会收到 CRC 错误;可能是压缩前或解压后的东西——无论如何,我担心这里可能没有足够的信息来解决问题。