从Golang中的二进制文件中读取int16

时间:2016-03-08 08:29:51

标签: go binary

我目前正在研究Golang程序,该程序从stdin读取一个16位整数。我期望值介于3到128之间,但是,当我打印出整数值时,它是完全随机的,从30,000+到-30,000。

我通过执行以下操作在PHP中执行相同的操作:

<?php

$binary = fread($stream, 2);
$unpacked = unpack('s', $binary);
$int = reset($unpacked);

这很有效。我正在处理的Go代码位于GitHub上:kantan.csv

我使用bash管道(例如cat testfile | command)将内容传输到程序中。

这是一些测试Golang代码:

package main

import (
    "bufio"
    "fmt"
    "encoding/binary"
    "io"
    "os"

    "github.com/layeh/gopus"
)

func main() {
    OpusDecoder, err := gopus.NewDecoder(48000, 2)
    if err != nil {
        panic(err)
    }
    _ = OpusDecoder

    dcabuf := bufio.NewReaderSize(os.Stdin, 16384)

    var opuslen uint16

    for {
        err = binary.Read(dcabuf, binary.LittleEndian, &opuslen)
        if err != nil {
            if err == io.EOF || err == io.ErrUnexpectedEOF {
                return
            }
            panic(err)
        }

        fmt.Println("Frame Size:", opuslen)

        opus := make([]byte, opuslen)
        err = binary.Read(dcabuf, binary.LittleEndian, &opus)
        if err != nil {
            if err == io.EOF || err == io.ErrUnexpectedEOF {
                return
            }
            panic(err)
        }

        // pcm, err := OpusDecoder.Decode(opus, 1920, false)
        // if err != nil {
        //     panic(err)
        // }

        // err = binary.Write(os.Stdout, binary.LittleEndian, &pcm)
        // if err != nil {
        //     if err == io.EOF || err == io.ErrUnexpectedEOF {
        //         return
        //     }
        //     panic(err)
        // }
    }
}

我希望输出与Frame Size: 128类似,但值要高得多。

我已在我的Google云端硬盘上传了一个测试文件:https://github.com/uniquoooo/dca/blob/decoding/main.go#L502-L536

要运行该程序,请使用go build构建它,然后运行如下:

cat test.dca | ./main

可执行文件名可能不同。

1 个答案:

答案 0 :(得分:0)

听起来你正在编码字节。换句话说,1变为49等(取决于编码)。解决这个问题的方法是将字节归一化为int16中每个字节的表示值(例如byte-'0')。

你可以做到这一点的可行方法是

a := uint16(((opuslen & 0xff00) >> 8) - '0')
b := uint16((opuslen & 0x00ff) - '0')
opuslen = (function to splice together)

虽然这是一件苦差事,但这是你必须要做的,以确保字节不维持其编码。那,或者只是不存储为utf / ascii /任何编码值。在拍摄它时会对人类看起来很时髦,但是是谁在乎:)

你还会注意到我将opuslen改为uint只是为了便于演示。如果您期望负长度(表示压缩可能?),则根据需要进行调整。

编辑: 如果你真的打算使用编码字节,也许你应该读入一个字符串并使用strconv.Atoi,这将使你更容易,因为你不必自己编写代码进行转换。