[2005] Reading Binary File
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?? :confused: 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
Re: [2005] Reading Binary File
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?
Re: [2005] Reading Binary File
Thanks for the quick reply jmcilhinney :thumb:
Will look into using the Binary Reader as suggested.
Re: [2005] Reading Binary File
I've found this example which reads the entire file but can't work out how to transfer the info into my tCatFormat structure?
vb Code:
' Open the file.
Dim fs As New IO.FileStream("cat.ind", IO.FileMode.Open)
' Create a BinaryReader for the FileStream.
Dim binary_reader As New IO.BinaryReader(fs)
fs.Position = 0
'ReDim tCatFormat((fs.Length / 50) - 1)
' Read the data as a byte array.
Dim bytes() As Byte = _
binary_reader.ReadBytes(fs.Length)
binary_reader.Close()
fs.Dispose()
Re: [2005] Reading Binary File
Post the VB6 code too. I don't think vb.net offers fixed strings unless you use marshalling but I think this would be an overkill.
Re: [2005] Reading Binary File
Here is the code to do the same thing in VB6.
vb Code:
Private Type UDTCatFormat
sCode As String * 5
sName As String * 10
sSector As String * 36
End Type
Dim tCatFormat() As UDTCatFormat
Private Sub Command1_Click()
Open App.Path & "\cat.ind" For Binary As #1
ReDim tCatFormat((LOF(1) / 50) - 1)
Get #1, , tCatFormat()
Close #1
End Sub
Re: [2005] Reading Binary File
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.
Re: [2005] Reading Binary File
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.
1 Attachment(s)
Re: [2005] Reading Binary File
Quote:
Originally Posted by Half
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)