在第一次写入后写入终止符(即ox1e)失败

时间:2017-12-28 03:05:06

标签: go

我正在尝试使用go(版本1.9.2)创建一些数据(实际上是MARC记录),我无法弄清楚如何将分隔符写入输出文件。

下面的代码段是我能够提出的最接近的示例。第一个项目使用适当的终结符编写,但之后没有其他内容。

在go中编写这些终结符字符的最佳/正确方法是什么?

const fieldTerminator = 0x1e

func main() {
    data := []string{"item one", "item two", "item tre"}

    writer, err := os.Create("x.out")
    if err != nil {
        log.Fatalf("Could not open file: %q\n", err)
    }
    defer writer.Close() // per biosckon

    ft := make([]byte, 2)
    binary.LittleEndian.PutUint16(ft, uint16(fieldTerminator))

    for _, d := range data {
        // this just proves to me that the loop is working
        //os.Stderr.WriteString(fmt.Sprintf("d is %q\n", d))
        fmt.Fprintf(os.Stderr, "d is %q\n", d) // per Andy Schweig

        _, err := writer.Write([]byte(d))
        if err != nil {
            log.Fatalf("%q\n", err)
        }

        // This prints the correct character at the end of the first item
        // and nothing after that (items 2 and 3 not printed, no errors):
        _, err = writer.Write(ft)
        if err != nil {
            log.Fatalf("%q\n", err)
        }
    }
}

修改更新了代码段,以解决Andy Schweig和biosckon的建议。

1 个答案:

答案 0 :(得分:0)

问题在于如何使用binary.LittleEndian.PutUint16。

所需要的是字段终结符的单字节。 PutUint16的结果是两个字节,终结符字节和空字节(如果将ft定义为一个字节并且没有PutUint8,则PutUint16不起作用。因此修复是在删除空字节之后截断ft

以下按要求工作:

const fieldTerminator = 0x1e

func main() {
    data := []string{"item one", "item two", "item tre"}

    writer, err := os.Create("x.out")
    if err != nil {
        log.Fatalf("Could not open file: %q\n", err)
    }
    defer writer.Close()

    ft := make([]byte, 2)
    binary.LittleEndian.PutUint16(ft, uint16(fieldTerminator))
    ft = ft[:1] // Truncate ft to a single byte

    for _, d := range data {
        _, err := writer.Write([]byte(d))
        if err != nil {
            log.Fatalf("%q\n", err)
        }

        _, err = writer.Write(ft)
        if err != nil {
            log.Fatalf("%q\n", err)
        }
    }
}