I'm trying to figure out how the best way to write a binary file in Go that corresponds with the following Python:
import struct
f = open('tst.bin', 'wb')
fmt = 'iih'
f.write(struct.pack(fmt,4, 185765, 1020))
f.close()
I have been tinkering with some of the examples I've seen on Github.com and a few other sources but I can't seem to get anything working correctly. What is the idiomatic way to do this sort of thing in Go?
Here is how I am accomplishing this now (Golang):
package main
import (
"fmt"
"os"
"encoding/binary"
)
func main() {
fp, err := os.Create("tst.bin")
if err != nil {
panic(err)
}
defer fp.Close()
aBuf := make([]byte, 4)
bBuf := make([]byte, 4)
cBuf := make([]byte, 2)
binary.LittleEndian.PutUint32(aBuf, 4)
binary.LittleEndian.PutUint32(bBuf, 185765)
binary.LittleEndian.PutUint16(cBuf, 1020)
binary.Write(fp, binary.LittleEndian, aBuf)
binary.Write(fp, binary.LittleEndian, bBuf)
binary.Write(fp, binary.LittleEndian, cBuf)
}
Verified with this Python:
import numpy as np
data = np.fromfile('tst.bin', dtype='i4,i4,i2')
print(data)
After a little more tinkering and some feedback on another question I was able to come up with this (seems much cleaner but will post feedback on performance after testing with generating some large files):
package main
import (
"os"
"encoding/binary"
)
type binData struct {
A int32
B int32
C int16
}
func main() {
fp, err := os.Create("tst.bin")
if err != nil {
panic(err)
}
defer fp.Close()
bd := binData{A:4, B:185765, C:1020}
binary.Write(fp, binary.LittleEndian, &bd)
}
As I mentioned in my question, I'm not sure this is THE idiomatic way to do this but after a fair bit of tinkering this does solve the problem I was having. Posting so there is at least one answer in case someone else comes looking:
package main
import (
"fmt"
"os"
"encoding/binary"
)
func main() {
fp, err := os.Create("tst.bin")
if err != nil {
panic(err)
}
defer fp.Close()
aBuf := make([]byte, 4)
bBuf := make([]byte, 4)
cBuf := make([]byte, 2)
binary.LittleEndian.PutUint32(aBuf, 4)
binary.LittleEndian.PutUint32(bBuf, 185765)
binary.LittleEndian.PutUint16(cBuf, 1020)
binary.Write(fp, binary.LittleEndian, aBuf)
binary.Write(fp, binary.LittleEndian, bBuf)
binary.Write(fp, binary.LittleEndian, cBuf)
}
Slightly cleaning this up to make it more brief I'll be doing something like this:
func main() {
fp, err := os.Create("tst.bin")
if err != nil {
panic(err)
}
defer fp.Close()
lineBuf := make([]byte, 10) //sized large enough to hold my two 4 byte ints and one 2 byte int
binary.LittleEndian.PutUint32(lineBuf[0:4], 4) //packing into 4 bytes
binary.LittleEndian.PutUint32(lineBuf[4:8], 185765)
binary.LittleEndian.PutUint16(lineBuf[8:10], 1020) //packing into 2 bytes
binary.Write(fp, binary.LittleEndian, lineBuf)
}