2 minutes
[Unity/Golang]データ圧縮にdeflateが使えなかった
お世話になっております。
しゃまとんです。
以前にデータ圧縮の記事を書いたのですが、
どうやら、Androidで利用しようとするとエラーになってしまうようです。
よって、モバイル向けに利用する際には注意が必要でした。
Unityでは(私個人が)大体モバイル向けにビルドするため、
これだと使えないということで別の手を使って圧縮を行うように変更することにしました。
deflateの代わりとしては、DotNetZipやMessagePackなども使えそうですが今回はSharpZibLibを使ってみることにしました。
ちなみにライセンスはMITです。以前はGPLだったようですが変わったみたいですね。
導入にはこちらのサイトがとても参考になります。
ということで、以前のコードを書き直しました。
Unity側はDeflateを使っていた箇所を置き換えるだけです。
using System.IO;
using ICSharpCode.SharpZipLib.GZip;
public class Compressor {
public static byte[] Compress(byte[] source) {
MemoryStream ms = new MemoryStream();
var CompressedStream = new GZipOutputStream(ms);
CompressedStream.Write(source, 0, source.Length);
CompressedStream.Close();
return ms.ToArray();
}
public static byte[] Decompress(byte[] source) {
MemoryStream ms = new MemoryStream(source);
MemoryStream ms2 = new MemoryStream();
var CompressedStream = new GZipInputStream(ms);
while (true) {
int rb = CompressedStream.ReadByte();
if (rb == -1) {
break;
}
ms2.WriteByte((byte)rb);
}
return ms2.ToArray();
}
}
サーバー側も下記のように修正しておきます。
func compress(target string) ([]byte, error) {
var buf bytes.Buffer
writer := gzip.NewWriter(&buf)
dat := bytes.NewBufferString(target)
if _, e := io.Copy(writer, dat); e != nil {
writer.Close()
return nil, e
}
e := writer.Flush()
if e != nil {
writer.Close()
return nil, e
}
e = writer.Close()
if e != nil {
return nil, e
}
return buf.Bytes(), nil
}
func decompress(compressed []byte) ([]byte, error) {
fr, e := gzip.NewReader(bytes.NewReader(compressed))
if e != nil {
fr.Close()
return nil, e
}
d, e := ioutil.ReadAll(fr)
if e != nil {
fr.Close()
return nil, e
}
e = fr.Close()
if e != nil {
return nil, e
}
return d, nil
}
これでAndroidでも使えるようになりました。
めでたしめでたし。以上です。