2016-10-09 27 views
5

私は非常に単純なGoウェブサーバを持っています。それは、受信Jsonペイロードを受信することです。次に、バイト配列を予期する1つ以上のサービスにペイロードをパブリッシュします。ペイロードはチェックする必要はありません。ちょうど送った。io.ReadCloserをバイト配列に変換する最も効率的な方法

この場合、受信ジョブを受信して​​Google PubSubに送信します。それは別のサービスかもしれません - それは本当に問題ではありません。 私はオブジェクトを最初にデコードせずにバイト配列に変換する最も効率的な方法を見つけようとしています。

なぜですか?デコードして1つのサーバー上のJSONに変換するのは少し無駄ですが、後で非マーシャリングするだけです。さらに、私は2つのパッケージに2つの同一の構造体を維持したくありません。

io.ReadCloserをバイト配列に変換することができますので、一度アンマーシャリングするだけで済みます。私はこの答えのようなものを試してみましたが、それはどちらかの最も効率的な方法だとは思わない:

From io.Reader to string in Go

私のhttpサーバのコードは次のようになります。

func Collect(d DbManager) http.HandlerFunc { 
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
    w.Header().Set("Content-Type", "application/json; charset=utf-8") 

    code := 422 
    obj := Report{} 
    response := Response{} 
    response.Message = "Invalid request" 

    decoder := json.NewDecoder(r.Body) 
    decoder.Decode(&obj) 

    if obj.Device.MachineType != "" { 
     msg,_ := json.Marshal(obj) 
     if d.Publish(msg, *Topic) { 
      code = 200 
     } 
     response.Message = "Ok" 
    } 

    a, _ := json.Marshal(response) 
    w.WriteHeader(code) 
    w.Write(a) 
    return 
}) 
} 

答えて

10

あなたはバイトにリーダーを変換する、ことにより、それを読む。本当に効率的な方法はありません。

body, err := ioutil.ReadAll(r.Body) 

あなたは無条件io.Writerio.Readerからバイトを転送している場合は、あなただけのio.Copy

+0

クールを使用することができ、私はそれを試してみましたと思いますが、それはnullを出力していた...私がしようとしていることを実現していませんでしたデコード後にこれを行うことができます。学んだ2つの教訓は、大きな耳を歓迎する。 –

+0

'io.Copy'は割り当てを行うことを覚えておくことをお勧めします。あなたはたぶんホットパスで 'io.CopyBuffer'を使いたいでしょう。 –

+1

@AmmarBandukwala、あなたが既にバッファを持っていない限り、それらは同一です、コピーはCoffyBufferを呼び出します。ある時点で割り当てを行う必要があり、std lib http要求のスキームでは、それは多くのそのような割り当ての1つで、重要ではないようです。 – JimB

関連する問題