createAndWriteSampleZdate() allocates a MallocMessageBuilder on the stack. The message is therefore destroyed when the function exits. However, you are returning a Zdate::Builder from that function. That builder is thus no longer valid -- it's effectively a dangling pointer. A debug build of your code should crash.
readZdate() has a similar problem.
More generally, it is not guaranteed that two messages with the "same" data will actually have identical bytes. Objects within the message can be allocated in arbitrary order.
If your goal is to write to a network channel, and you're using anything other than Windows, you can do so using writeMessageToFd(). On Windows, you should really create a subclass of kj::OutputStream which wraps the socket interface, then write to that. If you use messageToFlatArray(), you are forcing an extra unnecessary copy in order to put the message together into one contiguous array in memory.
Note that Cap'n Proto messages are self-delimiting, so you can use writeMessageToFd() (or writeMessage() on an arbitrary OutputStream) multiple times to send a stream of messages, without needing to write the size or any other delimiter in between.
> // is there a faster way to write the Array<word> to file?
Yes.
write(fd, array.begin(), array.size() * sizeof(word));
-Kenton