如何在Go中实现PHP的gzopen?

时间:2019-08-19 15:02:04

标签: php go

我必须将PHP脚本转换为Go,现在遇到了一个问题(我预计还会有更多问题)。

在脚本中,它使用gzopen打开.gz和非.gz文件,然后获取读取的数据并返回其MD5-hash版本。 我曾尝试使用zlib.NewReader,gzip.NewReader甚至flate,但它们无法正常工作。有人可以指出我正确的方向吗?

file, err := os.Open("somefile.dat")
if err != nil {
  return err
}

// rc := flate.NewReader(f) //error: corrupt input before offset 5
// rc, err := zlib.NewReader(f) //error: invalid header
// rc, err := gzip.NewReader(f) //error: invalid header
if err != nil {
  return err
}

buffer := make([]byte, 4096)
rc.Read(buffer)

注意:关于转换为MD5哈希,我遵循示例here 我最初使用md5.Sum(),但是返回了[Size] byte,其中Size为16bytes,这不是我所需要的。我必须将MD5校验和转换为32个字符的十六进制字符串,以使其与我需要的校验和相匹配。希望这对其他人有帮助。

1 个答案:

答案 0 :(得分:2)

由于您需要同时支持读取gzip和非gzip文件,因此请添加检查以查看if gzip.NewReader是否返回ErrHeader错误。如果返回该值,则退回以正常读取文件:

file, err := os.Open("somefile.dat")
if err != nil {
    return err
}

var rc io.ReadCloser
if gz, err := gzip.NewReader(file); err == gzip.ErrHeader {
    if _, err := file.Seek(0, io.SeekStart); err != nil {
        return err
    }
    rc = file
} else if err == nil {
    rc = gz
} else {
    return err
}

md5sum := md5.New()
if _, err := io.Copy(md5sum, rc); err != nil {
    return err
}

if err := rc.Close(); err != nil {
    return err
}

// TODO: md5sum.Sum