Question: I'm trying to read a collection dump generated by mongodump. The file is a few gigabytes so I want to read it incrementally.

I can read the first object with something like this:

```
buf := make([]byte, 100000)
f, _ := os.Open(path)
f.Read(buf)

var m bson.M
bson.Unmarshal(buf, &m)

```

However I don't know how much of the buf was consumed, so I don't know how to read the next one.

Is this possible with mgo?

Answer: 
Using mgo's `bson.Unmarshal()` alone is not enough -- that function is designed to take a `[]byte` representing a single document, and unmarshal it into a value.

You will need a function that can read the next whole document from the dump file, then you can pass the result to `bson.Unmarshal()`. 

Comparing this to `encoding/json` or `encoding/gob`, it would be convenient if `mgo.bson` had a `Reader` type that consumed documents from an `io.Reader`.

Anyway, from the [source for mongodump](https://github.com/mongodb/mongo/blob/master/src/mongo/tools/dump.cpp), it looks like the dump file is just a series of bson documents, with no file header/footer or explicit record separators.

[BSONTool::processFile](https://github.com/mongodb/mongo/blob/52bdc0125ac6ea0336f3da61bbfc8b0e92d9f6e5/src/mongo/tools/tool.cpp#L334) shows how mongorestore reads the dump file. Their code reads 4 bytes to determine the length of the document, then uses that size to read the rest of the document. Confirmed that the size prefix is part of the [bson spec](http://bsonspec.org/spec.html).

Here is a [playground example](http://play.golang.org/p/0HsqcfX_On) that shows how this could be done in Go: read the length field, read the rest of the document, unmarshal, repeat.
[Niks Keets' answer](https://stackoverflow.com/a/24240292/447492) did not work for me. Somehow `len(r.Data)` was always the whole buffer length. So I came out with this other code:

```
for len(buff) > 0 {
    messageSize := binary.LittleEndian.Uint32(buff)
    err = bson.Unmarshal(buff, &myObject)
    if err != nil {
        panic(err)
    }

    // Do your stuff

    buff = buff[messageSize:]
}

```

Of course you have to handle truncated strucs at the end of the buffer. In my case I could load the whole file into memory.