2016-05-22 69 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位。

相关问题