Resolved BinaryWriter and String variables

escheer

New member
Joined
Apr 25, 2020
Messages
3
Programming Experience
10+
My application uses a BinaryWriter filestream to create its data (instead of an actual database). I have both numeric and string variables. According to the docs,, the strings are actually written with a length-prefix value before the actual string and supposedly this is a two-byte variable. When I check the stream position after a string is written, it only appears to be a one-byte prefix. What am I not understanding correctly here? Does the prefix change size depending on the string variable length? I understand you don't actually read the prefix in the BinaryReader stream, it's internal, but the position within the stream is critical. There are situations where I need to skip over some variables in the data (using the stream seek with an offset), so accounting for these additional string variable prefixes is required.
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,439
Location
Norway
Programming Experience
10+
supposedly this is a two-byte variable
No, docs says it writes the prefix as unsigned integer. I would have thought that was 4 bytes, but it actually uses its protected Write7BitEncodedInt method for this, which "Writes a 32-bit integer in a compressed format". The format is LEB128 and can use 1-5 bytes to express the prefix integer number.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,349
Location
Sydney, Australia
Programming Experience
10+
You should just read all the records one by one and discard the ones you don't need. If there is so much data that that is a problem then you should be using a database in the first place.
 

escheer

New member
Joined
Apr 25, 2020
Messages
3
Programming Experience
10+
You should just read all the records one by one and discard the ones you don't need. If there is so much data that that is a problem then you should be using a database in the first place.
I'm skipping certain FIELDS within records, not entire records. It's not the volume of data that's an issue. I'm an old Fortran programmer from the 70's and I'm converting an old application I wrote back then to vb.net to learn a new language. It used binary files instead of a real database so I'm extremely familiar with how it all works. Once this is done, I may convert to using a database. I'm retired now, so I might just convert this to python when I'm finished. Just because I can...
Thanks for your response.
 

escheer

New member
Joined
Apr 25, 2020
Messages
3
Programming Experience
10+
No, docs says it writes the prefix as unsigned integer. I would have thought that was 4 bytes, but it actually uses its protected Write7BitEncodedInt method for this, which "Writes a 32-bit integer in a compressed format". The format is LEB128 and can use 1-5 bytes to express the prefix integer number.
Perfect! I didn't see that method specified and was expecting a UTF-16 which is 2 bytes, so the documentation wasn't clear enough to me. I'm using fixed-length strings in my code and all the strings are much shorter than 127 bytes, so the prefix will always be 1 byte long. That's all I needed to know. Thanks for your help!
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,349
Location
Sydney, Australia
Programming Experience
10+
I'm skipping certain FIELDS within records, not entire records.
So what? That just means that you should read all the fields and discard the ones you don't want. You really ought to have already written a single method that reads the next record and returns the field values as an object of some type, be it an array, a Tuple or a dedicated class. You can then wrap a call to that in another method that picks out the fields you want. You're just complicating things for no good reason.
 
Top Bottom