Protobuf.js: Writing a list of buffers to file

Created on 27 Jul 2017  路  4Comments  路  Source: protobufjs/protobuf.js

protobuf.js version: 6.8.0

I need to write to a file a list of encoded buffers.
I start with a regular list listReg=[{'name':"Jane",'id':1}...{}]
And I produce a list listOFEncoded where each item in the list is encoded as:

var fs = require("fs");
var protobuf = require("protobufjs");


protobuf.load("example.proto")
    .then(root=>{
        var listOFEncoded = [];
        for(var i =0; i< listReg.length; i++){
             var person = root.lookupType("Person");
            var message = person.create(listReg[i]);
            listOFEncoded.push(person.encode(listReg[i]).finish());    
        }

})  .catch(e=>{
    console.log(e.stack)
})

So What I want is to write listOFEncoded to a file and get the same output as if I encoded in this way:

fs = require("fs");
var protobuf = require("protobufjs");

protobuf.load("example.proto")
    .then(root=>{ 
        var size = 0;
        var MessageParser = root.lookupType("AddressBook");
        var message = MessageParser.create([]);
        for(var i =0; i< listReg.length; i++){

             message.imp.push(listReg[i]);
        }

        var buffer = MessageParser.encode(message.finish());
        fs.writeFile('out',buffer);

})  .catch(e=>{
    console.log(e.stack)
})

Just of clarity
console.log(listOfEncoded)

>>>[<Buffer 0a 23 08 00 10 94...>,<Buffer 06 40 cf 02 48 00 50 00 58>]

The use case in mind is that I need at any point in time to know the file size (of encoded), and the file size that will be if an arbitrary message is added to it.
So I need to have the size of an encoded item - and for that I might as well encode one item at a time.

question

All 4 comments

You could use SomeMessage.encodeDelimited to create length-prefixed buffers (this prepends the byte length as a varint to each message) and concatenate them to a single buffer.

var writer = protobuf.Writer.create();
persons.forEach(person => Person.encodeDelimited(person, writer));
var myConcatenatedBuffer = writer.finish();

A Reader is then able to decode one message at a time:

var reader = protobuf.Reader.create(myConcatenatedBuffer);
while (reader.pos < reader.len) {
  var person = Person.decodeDelimited(reader);
  console.log(person);
}

@dcodeIO
Thanks, that indeed did the trick.
I just had to create a new reader function in python to read it (As opposed to the other method of writing in nodejs).
馃憤

@dcodeIO, I have a couple of related questions, could you please clarify them for me?

  1. Is there a way to get the number of entities in a concatenated buffer without decoding everything?
  2. Is there a way to start decoding from a given entity position?

decodeDelimited reads the prefixed length of the message first, so one could use the reader to read just the lengths and skip to the next message, for instance to count the number of messages or start decoding at a given position.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yavin5 picture yavin5  路  5Comments

mj-mehdizadeh picture mj-mehdizadeh  路  5Comments

terranmoccasin picture terranmoccasin  路  5Comments

ghost picture ghost  路  3Comments

jarvanxing picture jarvanxing  路  4Comments