dtp19819 2017-12-28 03:05
浏览 88
已采纳

首次写入后写入终止符(即ox1e)失败

I have some data (MARC record actually) that I'm trying to create using go (version 1.9.2) and I can't figure out how to get the delimiting characters written to the output file.

The snippet below is an example of the closest that I've been able to come up with. The first item gets written with the appropriate terminator but nothing else after that.

What is the best/correct way to write these kinds of terminator characters in 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
", 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
", d))
        fmt.Fprintf(os.Stderr, "d is %q
", d) // per Andy Schweig

        _, err := writer.Write([]byte(d))
        if err != nil {
            log.Fatalf("%q
", 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
", err)
        }
    }
}

Edit: updated code snippet to address suggestions by Andy Schweig and biosckon.

  • 写回答

1条回答 默认 最新

  • dsf6565 2017-12-29 15:31
    关注

    The problem is with how binary.LittleEndian.PutUint16 was being used.

    What is required is a single byte for the field terminator. The result of PutUint16 is two bytes, the terminator byte and a null byte (PutUint16 doesn't work if ft is defined as one byte and there is no PutUint8). So the fix is to truncate ft after the fact to remove the null byte.

    The following works as required:

    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
    ", 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
    ", err)
            }
    
            _, err = writer.Write(ft)
            if err != nil {
                log.Fatalf("%q
    ", err)
            }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制