2

Golangでバイトストリームをバイトストリームスライスに変換する最良の方法は何ですか? 現在、golang で Java プログラムを複製しようとしていますが、Java がバイトストリームを符号付きの値として読み取るのに対し、golang はそれを符号なしの値として扱うという事実に問題があると思います。

Java で印刷すると、負の値が異なることに注意してください。ポジティブは同じです:

ジャワ:

8| -8 | -58 |-61|-56|-113|42|16|-64|2|24|-16|1

ゴーラン:

8| 248 | 198 |195|200|143|42|16|192|2|2|240|1

現在、GO での私の実装は次のようになります。

//open the file with os.open
//create new reader and unzip it

//reads from zip file and returns an array of bytes associated with it.
data, err := ioutil.ReadAll(fz)
if err != nil {
    return nil, err
}
//reflect.TypeOf shows this is a []uint8
//I want this to be a []int8 (so signed). 

Java では、実装はほとんど次のようになりました。

  //create buffer reader
  //create input stream
  //create datainput stream
  //use the .Read function to get the values required. 

それを符号付き int にすばやく型キャストする簡単な方法がわかりませんでした (おそらく私が間違っているかもしれません)。各値を signed int に変換して、スライス全体を反復処理することもできますが、その方法はやや面倒です。また、それぞれを操作する必要があります。スライスを変換するよりクリーンな方法はありますか?

4

3 に答える 3

4

明確にするべきいくつかのこと: Java と Go の両方が、ファイルから同じ方法でデータを読み取ります。

ファイルは、バイトと呼ばれる 8 ビットでグループ化された一連のバイナリ データです。このバイトは 8 ビットで、どのように解釈するかは完全にあなた次第です。

Go と Java はどちらも同じ 8 ビット グループを読み取りますが、Java はそれを符号付きの Javabyte型に格納し、Go はunsignedの Go型に格納します。しかし、どちらも同じ 8 ビットを持つため、読み取ったデータは等しくなります。byte

var b byte = 248
var i int8 = -8
fmt.Printf("%x %x\n", b, byte(i))

出力:

f8 f8

読み取った 8 ビットを符号付きの値として解釈する必要がある場合は、単純に型変換を使用します。

data := []byte{8, 248, 198}
for _, v := range data {
    fmt.Println(int8(v))
}

出力 (Java 出力と同じ):

8|-8|-58|

Go Playgroundで例を試してください。

(型変換のため) パフォーマンスを気にする必要がありますか? 絶対違う。byte->int8どちらも同じメモリ レイアウト (つまり、8 ビット = 1 バイト) を持っているため、変換にはランタイム コストはかかりません。

于 2016-05-22T17:29:46.377 に答える
1

上記の安全でない回答はまったく問題ありませんが、appengine では機能しません。

安全なバージョンは次のとおりです。

signed := make([]int8, len(unsigned))
for i, v := range unsigned {
    signed[i] = int8(v)
}

playground

于 2016-05-22T16:06:15.480 に答える