在网络上读和写Conn

I am trying to read and write data from a net.Conn but since I have only Read([]byte) and Write([]byte) functions, I am finding quite hard to find helper functions to do this job.

I need to read and write the following types:

  • uint64
  • byte
  • uint32
  • UTF-8 encoded string ( first a uint32 length and the string data after)

In Short

Is there anything like Java's DataInputStream and DataOutputStream in Go's packages ?

Thanks and regards

One little secret of binary encoding is that you can write and read entire data structures:

From the Playground

    buf := new(bytes.Buffer)
    err := binary.Write(buf, binary.LittleEndian, &MyMessage{
    First:   100,
    Second:  0,
    Third:   100,
    Message: MyString{0, [10]byte{'H', 'e', 'l', 'l', 'o', '
'}},
    })

if err != nil {
    fmt.Printf("binary.Read failed:", err)
    return
}

// <<--- CONN -->>
msg := new(MyMessage)

err2 := binary.Read(buf, binary.LittleEndian, msg)
if err2 != nil {
    fmt.Printf("binary.Read failed:", err2)
    return
}

Pay attention at the kind of types that you can use:

from binary/encoding docs:

A fixed-size value is either a fixed-size arithmetic type (int8, uint8, int16, float32, complex64, ...) or an array or struct containing only fixed-size values.

notice then that you have to use [10] byte and can't use []byte

You need to decide on a format to marshal to and from. Your choices are to either roll your own format or to use one that was already made. I highly recommend the latter.

I have previously posted about many of the formats supported in the go standard library here: https://stackoverflow.com/a/13575325/727643

If you decide to roll your own, then uints can be encoded and decoded from []byte using encoding/binary. It gives you the option of both little and big endian. Strings can be converted directly to []byte using []byte(str). Finally, bytes can just be sent as bytes. No magic needed.

I will stress that making up your own format is normally a bad idea. I tend to use JSON by default and use others only when I can get a significant performance increase and I believe it worth the time to do it.

Fabrizio's answer is good and I would like to add that you should probably wrap your socket with a buffered reader and buffered writer from the bufio package:

http://golang.org/pkg/bufio/