• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 155
  • Last Modified:

Issue splitting up binary file

I need to split a binary file into 6 variables, two contain tempurture (3bytes), two contain pressure (3 bytes)  and  two contain time (2 bytes). The file contains multiple readings, each reading being 16 bytes (8 bytes per channel), stored on a single file which could range anywhere from 1kb to 10mb. What I need to do is split a reading from channel A into its 3 variables, and channel B into it's 3 variables and then run the data with some calculations (to get some real numbers, which is produced by running the HEX values contained in the binary file to some coefficients) Plot the data and then move on to the next reading in the file. The issue I am having is the logic needed to read the 16 bytes from the file, do the split, get my calcs, then go back to the file and get the next reading. This is because the data is stored sequentially on the file, with no characters used to split the data. I feel like my brain is going to explode as I have been fighting this for 3 days and I am getting frustrated to the max! Help!!!!! Thanks in advance, drinks are on me!!!!!

Thanks,

Brad

TOTAL 16 BYTES

XXX          XXX                          XX            XXX         XXX             XX

A TEMP      A PRESSURE        A TIME      B TEMP      B PRESSURE        B TIME
0
bradbritton
Asked:
bradbritton
  • 3
  • 2
1 Solution
 
ElrondCTCommented:
You want to open what VB calls a "Random" file. It's easiest to set up the record layout with a Structure.

    Private Structure Reading
        <VBFixedString(3)> Public ATemp As String
        <VBFixedString(3)> Public APressure As String
        <VBFixedString(2)> Public ATime As String
        <VBFixedString(3)> Public BTemp As String
        <VBFixedString(3)> Public BPressure As String
        <VBFixedString(2)> Public BTime As String
    End Structure

    Private Sub FileProcess()
        Dim fiCurrent As System.IO.FileInfo
        Dim lngFileLength, lngPos As Long
        Dim intPos As Integer
        Dim CurReading As Reading
        Dim strOutput(6) As String
        FileOpen(1, txtIn.Text, OpenMode.Random, OpenAccess.Read, _
            OpenShare.Default, Len(CurReading))
        fiCurrent = New System.IO.FileInfo(txtIn.Text)
        lngFileLength = fiCurrent.Length
        For lngPos = 1 To lngFileLength \ Len(CurReading)
            FileGet(1, CurReading, lngPos)
            strOutput(1) = CurReading.ATemp
            strOutput(2) = CurReading.APressure
            strOutput(3) = CurReading.ATime
            strOutput(4) = CurReading.BTemp
            strOutput(5) = CurReading.BPressure
            strOutput(6) = CurReading.BTime
            ' Do something with the data; you don't need to load it into the
            ' string array, but I'm showing you how to access it
        Next
    End Sub

txtIn.Text is the text box in which you enter the file name. You can replace it with a regular string variable if you prefer.
0
 
bradbrittonAuthor Commented:
Unfortunatly this solution tested and does not work. The data that is read is in bytes, and does not work as it only gets the first byte, not the necassary information.

Thanks,

Brad
0
 
ElrondCTCommented:
You're only getting one byte? That's certainly not what happened when I tested the code on my computer.

I'm not following the significance of your saying "the data that is read is in bytes"; everything is bytes on the disk, whether it should be understood as string, numeric, picture, or whatever other kind of data. Do you mean that the temperature is a 24-bit number, rather than three Ascii characters? If so, then you can either change the structure coding to an appropriate variable type, or once you've read it into a string, convert it to Ascii values by something like

Asc(CurReading.ATemp) * 65536 + Asc(CurReading.ATemp.Substring(2, 1)) * 256 + Asc(CurReading.ATemp.Substring(3, 1))

Is the data file still open by another program when you're trying to read it? If you put a breakpoint immediately after the FileGet, what does a Watch on all the members of CurReading give you? Is there text, or "Nothing", or what? What's the file length according to lngFileLength? Your description is too brief for me to fully understand why it's not working, and therefore how to solve it.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
bradbrittonAuthor Commented:
Yes that is correct, the data is read in 3 byte increments (temp/pressure) 2 bytes for time, and is not ascii characters. It is Hex values.
0
 
ElrondCTCommented:
OK, then you'll probably want to change the structure. I'm not aware of a data type is for a 3-byte number. Is this an integer value, or some sort of a floating-point format? Perhaps a better structure would be:

    Private Structure Reading
        <VBFixedString(3)> Public ATemp As String
        <VBFixedString(3)> Public APressure As String
        Public ATime As Int16
        <VBFixedString(3)> Public BTemp As String
        <VBFixedString(3)> Public BPressure As String
        Public BTime As Int16
    End Structure

or perhaps it's easier to separate out the individual bytes for the 3-byte numbers:

    Private Structure Reading
        <VBFixedString(1)> Public ATemp1 As String
        <VBFixedString(1)> Public ATemp2 As String
        <VBFixedString(1)> Public ATemp2 As String
        <VBFixedString(1)> Public APressure1 As String
        <VBFixedString(1)> Public APressure2 As String
        <VBFixedString(1)> Public APressure2 As String
        Public ATime As Int16
        <VBFixedString(1)> Public BTemp1 As String
        <VBFixedString(1)> Public BTemp2 As String
        <VBFixedString(1)> Public BTemp2 As String
        <VBFixedString(1)> Public BPressure1 As String
        <VBFixedString(1)> Public BPressure2 As String
        <VBFixedString(1)> Public BPressure2 As String
        Public BTime As Int16
    End Structure

You'd use the formula in my previous message to convert the three-byte strings to an integer. That does the hex valuation properly. If the value is in hundredths of a degree or some such, just divide the result by 100 and stick it in a Single or Double variable. I'm afraid I don't know of a more simple way to deal with a 3-byte number, though you might want to declare a little function to do the conversion:

Private Function ThreeByte(ByVal Byte1 as String, ByVal Byte2 as String, ByVal Byte3 as String) as Integer
   Return Asc(Byte1) * 65536 + Asc(Byte2) * 256 + Asc(Byte3)
End Function

Then call this with something like

intATemp = ThreeByte(CurReading.ATemp1, CurReading.ATemp2, CurReading.ATemp3)

But that's just playing with the bits. The major issue is why you're not getting data read in using FileGet. Let's do some more testing of what your program says is happening, and we can get that sorted out.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Hi again bradbritton...

Open it as a FileStream and then pass that to a BinaryReader.  Now you can use the ReadBytes() function:

        Dim fs As New System.IO.FileStream("c:\someFile.txt", IO.FileMode.Open)
        Dim br As New System.IO.BinaryReader(fs)

        Dim val() As Byte = br.ReadBytes(3)  ' read three bytes
        Debug.WriteLine(val(0).ToString)
        Debug.WriteLine(val(1).ToString)
        Debug.WriteLine(val(2).ToString)

        br.Close()
        fs.Close()
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now