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 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分