I've converted a small VB6 program into VB.Net that reads a binary file into a custom type array but it is skipping information. Below is the file format which you can see sCode, sName and sSector all have fixed lengths.
The issue is if a value read to sCode only has 3 characters the extra 2 characters assigned to sCode are removed so the length of the variable is now 3?? When I run it in VB6 the the 3 characters are read and 2 'spaces' are add to make sCode remain 5 characters in length.
How can I get VB.net to retain the fixed lengths to each variable even if the value read are not that length.?
I hope everything is clear as to what I'm after
Code:
Private Structure UDTCatFormat
'UPGRADE_WARNING: Fixed-length string size must fit in the buffer. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="3C1E4426-0B80-443E-B943-0627CD55D48B"'
<VBFixedString(5)> Dim sCode As String
'UPGRADE_WARNING: Fixed-length string size must fit in the buffer. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="3C1E4426-0B80-443E-B943-0627CD55D48B"'
<VBFixedString(10)> Dim sName As String
'UPGRADE_WARNING: Fixed-length string size must fit in the buffer. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="3C1E4426-0B80-443E-B943-0627CD55D48B"'
<VBFixedString(36)> Dim sSector As String
End Structure
Code:
Private Sub Command1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Command1.Click
Dim tCatFormat() As UDTCatFormat
ReDim tCatFormat((LOF(1) / 50) - 1)
'UPGRADE_WARNING: Get was upgraded to FileGet and has a new behavior. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
FileGet(1, tCatFormat)
FileClose(1)
End Sub
You should get rid of that VB6-style I/O and rewrite it in VB.NET. Use binary serialisation or a BinaryReader to read binary files.
This is a fine example of why upgrading applications is generally a bad idea. You should determine what functionality you need and then implement it in VB.NET in the best way you can. You'll often spend as much or more time fixing issues and still end up with worse code if you use the upgrade wizard.
By the way, did you read that upgrade warning and follow its advice, i.e. load that topic in the Help viewer?
And you need the first 5 symbols to go into tCatFormat.sCode, the next 10 into tCatFormat.sName and the last 36 into tCatFormat.sSector?
Or are those values somehow separated in your file, like on different lines? I mean how can you say if the first value is 3, 4 or 5 symbols. You could also upload a sample source file if it is not private stuff.
Half raises a good point and one I probably should have mentioned previously. There's no such thing as a fixed-length string in VB.NET. The conversion wizard has done the closest thing and added the VBFixedString attribute to those fields but that doesn't make them a fixed-length. It just makes them appear to be a fixed-length when passed to unmanaged code.
If you want to maintain a fixed length string then it's up to you to write the code to do it. You'd have to declare those fields Private and expose them via Public properties. You'd then have to validate the value in the setter and pad it if it was too short and either truncate it or throw an exception if it was too long.
As far as reading and writing the data to a file, I'd probably suggest using a more modern format/technology. I'd suggest serialising and deserialising the data to XML or binary files. That does mean that any files in the old format would be invalid though, so if that's a problem you could provide backward compatibility through a second reading routine but only write to the new format.
If you must stick with that format then look at the other methods that the BinaryReader provides. Noone's saying you have to read the whole file in one go. There's a ReadChars method for instance, which you could call three times.
If you file is actually just ASCII text then you should probably use a StreamReader rather than a BinaryReader, although StreamReader.Read will read into a Char array just like BinaryReader.ReadChars will. In both cases you'd have to create the object with an ASCIIEncoding to read single-byte characters.
And you need the first 5 symbols to go into tCatFormat.sCode, the next 10 into tCatFormat.sName and the last 36 into tCatFormat.sSector?
Correct
Attached is a sample file.
The first record for sCode should read "DDD " (note the 2 spaces)
The second record for sCode should read "TQHR " (note 1 space)
The third record for sCode should read "NHDHD" (all 5 characters used with text)