Почему я не могу распаковать данные gzip с помощью Go в моей демонстрации PHP, но данные PHP gzip для Go успешны? Мне нужно опубликовать gzip-данные JSON из сервиса Go to PHP API.
Результат испытаний
-> | php | go
---------------------
php | ok | ok
go | fail | ok
Код PHP
class GzipDemo
{
public function gzen($data, $file){
$json_data = json_encode($data);
$gz_data = gzencode($json_data,9);
file_put_contents($file,$gz_data);
}
public function gzdn($file){
$data = file_get_contents($file);
$unpacked = gzdecode($data);
if ($unpacked === FALSE)
{
print("failed:".$file."\n");
}else{
print($file. " result Data :".$unpacked ."\n");
}
}
}
$demo = new GzipDemo();
$file="phpgzip.txt";
$demo->gzen("data",$file);
$demo->gzdn($file);
$demo->gzdn("gogzip.txt");
Этот результат:
PHP в PHP все в порядке.
Перейти к PHP не удалось.
Перейти код
package main
import (
"bytes""compress/gzip""encoding/json""fmt""io/ioutil""os")
func main() {
gzen("data", "gogzip.txt")
gden("gogzip.txt")
gden("phpgzip.txt")
}
func gzen(data string, file string) {
b, _ := json.Marshal(data)
buffer := new(bytes.Buffer)
w, _ := gzip.NewWriterLevel(buffer, gzip.BestCompression)
defer w.Close()
w.Write(b)
w.Flush()
ioutil.WriteFile(file, buffer.Bytes(), os.ModePerm)
}
func gden(file string) {
b, _ := ioutil.ReadFile(file)
buffer := new(bytes.Buffer)
buffer.Write(b)
r, _ := gzip.NewReader(buffer)
defer r.close()
data, _ := ioutil.ReadAll(r)
fmt.Println(file, " result Data:", string(data))
}
Этот результат:
Иди иди хорошо.
PHP, чтобы идти хорошо.
Работает со следующими изменениями:
gzdecode
вместо gzinflate
, И тебе это не нужно substr($data, 10)
вещи, если вы используете это. Я не читал о том, как deflate относится к gzip, но простота в том, что gzencode
/gzdecode
соответствовать тому, что Голанг gzip
пакет делает и что gz*
семейство инструментов командной строки GNU.buffer
, Как вы можете видеть здесь: http://golang.org/src/compress/gzip/gzip.go?s=6230:6260#L240 есть некоторые дополнительные вещи, которые записываются в базовый поток при закрытии, поэтому в приведенном выше примере неполное. (The defer
причины заявления Close()
запускается после выхода из содержащей функции.) Скорее всего, декодирование Go gzip все равно удается декодировать, тогда как реализация PHP — нет — в любом случае вы должны правильно закрыть поток в буфере в памяти, чтобы убедиться, что он завершен, прежде чем писать его в файл.ОБЯЗАТЕЛЬНОЕ ПРИМЕЧАНИЕ. Вы игнорируете все свои ошибки в своем коде Go. Этот код выглядит просто как тест, поэтому я не буду вдаваться в подробности, но вы определенно хотите делать правильную обработку ошибок (либо сообщать о проблеме пользователю, либо вызывающей стороне вашей функции).
Других решений пока нет …