2016-05-22 115 views
1

在Golang中將字節流轉換爲字節流片段的最佳方式是什麼?目前我正在嘗試在golang中複製一個java程序,我相信我有一些事實,即java將字節流作爲有符號值讀取,而golang將其視爲無符號值。將無符號字節流轉換爲有符號字節流Golang

當我用Java打印時,負值是不同的。正面都是一樣的:

的Java:

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

Golang:

8 | | | 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. 

我沒有看到任何簡單的方法來快速將它轉換爲signed int(也許我錯了)。我可以嘗試迭代整個切片,將每個值轉換爲帶符號的int,但是這種方法似乎相當混亂。這也需要我對每一個進行操作。有沒有一種更清晰的方式來轉換切片?

+0

http://stackoverflow.com/q/12357865/4740606和http://stackoverflow.com/q/28949063/4740606的最佳答案可能對您有所幫助 – Snowman

回答

3

如果您知道正好您正在做的事情,您可以使用unsafe.Pointer。因爲顧名思義,這是不安全的。因此,如果你不明智地使用它,它會炸燬。

package main 

import (
    "fmt" 
    "unsafe" 
) 

func main() { 
    unsigned := make([]uint8, 0) 
    unsigned = append(unsigned, 128) 
    unsigned = append(unsigned, 255) 

    signed := *(*[]int8)(unsafe.Pointer(&unsigned)) 
    fmt.Printf("%d : %d\n", signed[0], unsigned[0]) 
    fmt.Printf("%d : %d\n", signed[1], unsigned[1]) 
} 
// -128 : 128 
// -1 : 255 

您可以找到Go playground

+0

雖然不安全的操作會引起恐慌,但這似乎奏效我一點點。將玩這個,以確保我完全理解這一點 – and0rsk

1

以上不安全的答案是完全沒有這個例子,但是它不會AppEngine上工作。

這裏是安全的版本:

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

playground

2

有些事情要明確:Java和去讀取數據從文件的方式。

文件是按8位分組的二進制數據序列,我們稱之爲字節。這字節是8位,你如何解釋它完全取決於你。

一起去,Java將讀取相同的8位組,但Java將其存放在一個Java byte型這是一種簽署型,與圍棋將其存儲在一個圍棋byte類型,是無符號 。但兩者具有相同的8位,讀取數據將是平等的:

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

輸出:

f8 f8 

如果您需要解釋讀取8位作爲一個符號的值,只需使用一個類型conversion

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

輸出(作爲Java輸出相同):

8|-8|-58| 

試試Go Playground上的示例。

如果您擔心性能(因爲類型轉換)?絕對不。 byte - >int8轉換沒有運行時間成本,因爲它們都具有相同的存儲器佈局(即8位= 1字節),並且轉換隻是告訴以不同的方式解釋這8位。

相關問題