Google Answers Logo
View Question
 
Q: Visual Basic Binary file access ( Answered 4 out of 5 stars,   1 Comment )
Question  
Subject: Visual Basic Binary file access
Category: Computers > Programming
Asked by: watergeo-ga
List Price: $30.00
Posted: 01 Nov 2002 06:31 PST
Expires: 01 Dec 2002 06:31 PST
Question ID: 95319
How do I read in elements of a Binary file created in another
application from visual basic?  I know the structure of the file, for
instance I know where the tags for different sections of the file are.

I can provide details on the file structure.  I would need sample code
to consider the answer successful.

Request for Question Clarification by hammer-ga on 01 Nov 2002 07:18 PST
Hi Watergeo,

Visual Basic provides file access functions to do what you ask. In
order to provide good sample code, I do need the file structure. It
would also be helpful if you could post the actual file somewhere I
can get to it.

Hammer

Request for Question Clarification by mathtalk-ga on 02 Nov 2002 06:59 PST
Watergeo-ga, would you also please mention which version of Visual
Basic you are using.  The differences between VB 6.0 and VB.Net are
significant, but so are the similarities.

The short answer is that you would use a built-in function FileOpen,
which associates a file number with a file name, to set the "mode" of
the file to BINARY (passed as the required third argument).

You mention that you know the "location" of the tags within the file
that identify sections within the structure.  You might post those
details or at least clarify whether by "location" you mean fixed
positions or simply the possible "sequences" of tags.

regards, mathtalk-ga
Answer  
Subject: Re: Visual Basic Binary file access
Answered By: theta-ga on 02 Nov 2002 09:14 PST
Rated:4 out of 5 stars
 
Reading binary data in VB is really quite easy. I'm am providing some
example code here, with pointers to articles you might refer to in
case you want more examples or explainations.
Here, I will try to read a record ExampleData from a binary file.
Since you say that you already know the binary file record structure,
you can substitute my ExampleData structure with your own record
structure.
I have included code for both VB 6 & VB 7.NET
Explaination of code snippets : I try to read/write a fixed length
record from/to a binary file.The record contains a fixed length string
of 10 chars and an integer value. I first write one record of this
type to the file and then read one record from the file in binary
mode.I also show you how to get the length of an open file in VB.

CODE SNIPPETS FOR VB5/VB6
--------------------------
   'Define ExampleData structure
   Type Exampledata
         Name as String * 10  'This is a fixed length string of 10
characters
         Age as Integer
   End Type
   Dim myData As ExampleData  ' Declare variable of type ExampleData

   ...

   'Open Binary File
   'FOr Binary Access, The Open function has the following format :
   'Open filename For Binary As filenumber
    Open "c:\BinaryFile.bin" For Binary As #1
    
   'When writing to a binary file, we use the Put statement.
   'Put #FileNumber, ByteNumber, VariableName
   'ByteNumber is the file pos from which we start writing the data 
   Put #1,,myData  ' Writes mydata in file at the current position 

   'Close the file
   Close #1
   
 ....
 
   'Read data from the file
   Open "c:\BinaryFile.bin" For Binary As #1
   'To read data, use the Get function
   'Get #FileNumber, ByteNumber, VariableName
   'Data is read from the binary file position specified by ByteNumber
   Get #1,,myData 'Read in data from the current file pos
   'Print Data
   Debug.Print myData.Name
   Debug.Print myData.Age
   'To get the length of file, use the LOF(filenumber) function
   Debug.Print "Length of the Binary File = " & LOF(1)
   'Close File
   Close #1

  RELATED LINKS
  -------------
   - Binary Files - File Access by James Crowley
     A very good tutorial On using Binary Files under VB. Highly
recommended!
     ( http://www.developerfusion.com/show/85/1/ )
   - MSDN Help topic: "Using Binary File Access"
     The standard MS Help Article on Binary files in VB 6
     ( http://msdn.microsoft.com/library/devprods/vs6/vbasic/vbcon98/vbconusingbinaryfileaccess.htm
)
   - MS KnowledgeBase Q257794 - HOWTO: Use Binary File Access with
Visual Basic
     Adds to the above MSDN Article. Provides example code for
variable length records access in a binary file using VB.
     ( http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q257794&
)
   - MS Support : File Access with Visual Basic® for Applications
     Although for VBA, the same code works for VB6. Provides a list of
all the functions that can be used with the Binary file Access mode in
VB.Also provides example code.
     ( http://support.microsoft.com/default.aspx?scid=/support/excel/content/fileio/fileio.asp
)
======================

CODE SNIPPETS FOR VB7.NET
-------------------------
   'Define ExampleData structure
   Structure Exampledata
     <VBFixedString(10)>  Name as String 'Fixed length string of 10
characters
         Age as Integer
   End Type
   Public myData As ExampleData  ' Declare variable of type
ExampleData
   
   ...

   'Open Binary File
   'For Binary Access, use the FileOpen function which has the form :
   'FileOpen(FileNumber, FileName, OpenMode.Binary)
    FileOpen (1,"c:\BinaryFile.bin", OpenMode.Binary
    
   'When writing to a binary file, we use the FilePut() function.
   'FilePut( FileNumber,VariableName)
   FilePut(1,myData)  ' Writes mydata in file at the current position

   'Close the file
   FileClose(1)
   
 ....

   'Read data from the file
   FileOpen (1,"c:\BinaryFile.bin", OpenMode.Binary
   'To read data, use the FileGet function
   'FileGet (FileNumber, VariableName)
   FileGet(1,myData) 'Read in data from the current file pos
   'Display length of open file using the func. LOF(filenumber)
   Debug.WriteLine(LOF(1))
   'Close File
   FileClose(1)

 RELATED LINKS
 -------------
 - MSDN VB.NEt File Functions Reference
     - FileOpen()
       ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vblr7/html/vastmopen.asp
)
     - FilePut()
       ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vblr7/html/vastmput.asp
)
     - FileGet()
       ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vblr7/html/vafctget.asp)
     - LOF()
       ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vblr7/html/vafctlof.asp
)

MSDN Article : Binary File Access
( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcn7/html/vaconopeningfileforbinaryaccess.asp
)

===========================
I hope the above answer will satisfy your needs.
If you need any clarifications, just ask.
Till the, Happy Coding !
:)

Request for Answer Clarification by watergeo-ga on 02 Nov 2002 18:32 PST
The code structure is as follows.  What I want to do is read the
header sections and tags and write those to another file.  Then loop
through the data section modifying the values and writing them back
into a file with the same structure.  I just still don't understand
how to read in values of a file without knowing exactly howlong the
variables are.

Here is the structure:

Surfer 7 grid files [.GRD] use a tag-based binary format to allow for
future enhancements.  Each section is preceded by a tag structure,
which indicates the type and size of the following data.  If a program
does not understand or want a particular type of data, it can read the
associated tag and quickly skip to the next section.  In general,
sections can appear in any order except for the first, which must be a
Header section.

Data types used in Surfer 7 grid files:

Type	Description
long	32 bit signed integer
double	64 bit double precision floating point value
Each section is preceded by a tag structure with the following format:

Element	Type	Description
Id	long	The type of data in the following section.  See the next table
for a list of valid values.
Size	long	The number of bytes in the section (not including this tag).
 Skipping this many bytes after reading the tag will align the file
pointer on the next tag.
Tag Id values.  The 0x prefix indicates a hexadecimal value:

Id	Description
0x42525344	Header section – must be the first section within the file.
0x44495247	Grid section – describes a 2D matrix of Z values.
0x41544144	Data section – contains a variable amount of data.  The
size of the data section is given by the Size field in the tag
structure.
0x49544c46	Fault Info section – describes the fault traces used when
creating the grid.
The Header section must be the first section in the file and has the
following format:

Element	Type	Description
Version	long	Version number of the file format.  Currently must be set
to 1.
The Grid section consists of a header that describes a 2D matrix of
values, followed by the matrix itself.  This section encapsulates all
of the data that was traditionally referred to as a grid:

Element	Type	Description
nRow	long	number of rows in the grid
nCol	long	number of columns in the grid
xLL	double	X coordinate of the lower left corner of the grid
yLL	double	Y coordinate of the lower left corner of the grid
xSize	double	spacing between adjacent nodes in the X direction
(between columns)
ySize	double	spacing between adjacent nodes in the Y direction
(between rows)
zMin	double	minimum Z value within the grid
zMax	double	maximum Z value within the grid
Rotation	double	not currently used
BlankValue	double	nodes are blanked if  greater or equal to this value
A Data section containing the 2D matrix of values must immediately
follow a Grid section.  Within the Data section, the grid is stored in
row-major order, with the lowest row (minimum Y) first

A Fault Info section describes the fault geometry used to create the
grid.  Fault Info sections have the following format:

Element	Type	Description
nTraces	long	number of fault traces (polylines)
nVertices	long	total number of vertices in all the traces
data section		variable-sized data block consisting of an array of
Trace structures immediately followed by the array of vertices
A Data section containing an array of Trace structures and an array of
Vertex structures must immediately follow a Fault Info section.  The
number of Trace structures in the array is nTraces, and the number of
Vertex structures is nVertices.

Trace structure:

Element	Type	Description
iFirst	long	0-based index into the vertex array for the first vertex
of this trace
nPts	long	number of vertices in this trace
Vertex structure:

Element	Type	Description
x	double	X coordinate of the vertex
y	double	Y coordinate of the vertex
Example
The following example illustrates the layout for a 5 row by 10 column
grid:

Element	Type	Description
0x42525344	long	Tag:  Id for Header section
4	long	Tag:  Size of Header section
1	long	Header Section: Version
0x44495247	long	Tag:  ID indicating a grid section
72	long	Tag:  Length in bytes of the grid section
5	long	Grid Section:  nRow
10	long	Grid Section:  nCol
0.0	double	Grid Section:  xLL
0.0	double	Grid Section:  yLL
1.0	double	Grid Section:  xSize
1.75	double	Grid Section:  ySize
25.0	double	Grid Section:  zMin
101.6	double	Grid Section:  zMax
0.0	double	Grid Section:  Rotation
1.70141e38	double	Grid Section:  BlankValue
0x41544144	long	Tag:  ID indicating a data section
400	long	Tag:  Length in bytes of the data section (5 rows x 10
columns x 8 bytes per double)
Z11, Z12, …	double	Data Section:  First (lowest) row of matrix.  10
doubles
Z21, Z22, …	double	Data Section:  Second row of matrix.  10 doubles
Z31, Z32, …	double	Data Section:  Third row of matrix.  10 doubles
Z41, Z42, …	double	Data Section:  Fourth row of matrix.  10 doubles
Z51, Z52, …	double	Data Section:  Fifth row of matrix.  10 doubles

Request for Answer Clarification by watergeo-ga on 02 Nov 2002 18:35 PST
You provide an example of reading a file when you know exactly how
long the variables are.  Please provide an example of reading one when
you do not know how long the variables are.  See my comments for info
on the file structure.

-Watergeo

Clarification of Answer by theta-ga on 03 Nov 2002 12:09 PST
Silly Me! In my hurry, I posted my clarification as a Comment!
Well here it is again...
================================
water-geo, I am a little short on time today and so will not be able
to give a very in-depth tutorial on this matter, but i hope to make
the basics clear enough for you to solve this problem on your own. If
you still need any clarifications, i will gladly help you tomorrow.
BTW : Please specify which version of VB you are working with, in the
following example i assume you are using VB6.
----------- 
First of all here are the VB6 data types you use : 
Data Type          VB6 Data Type   VB7.NET Data types 
32 bit Integer  -    Long        -     Integer  
64 bit double   -    Double      -     Double 
 
Id Description : To represent a hexadecimal value in VB6, you replace
the '0x' with '&H'. So the value 0x42525344 will be represented in VB6
as &H42525344
 
Ok, so you can create your header element like this : 
Const HEADER_ID as Long = &H42525344  
 Type ElementHeader 
      Id as Long 
      Size as Long 
      Version as Long 
 End Type  
 
dim Header as ElementHeader 
 
'Open the file as shown in the answer 
'While not End of file 
'Read Header element as it must be the first 
Get 1,,Header 
if header.Id <> HEADER_ID then 
  ' ERROR! First element in file is not Header Element 
end if 
'Close File 
 
I hope this helped you get the idea. I am currently generating this
code off the top of my head so please forgive any syntax errors i
make.
 
Now to read the Data Grid : 
You can define & read a grid element easily, it is a fixed length
record and the method to read it is the same as what is shown in case
of the HeaderElement.
Type ElementGrid 
    Id as... 
    Size as ... 
    nRow as Long 
    nCol as Long 
    <other variables>.... 
End Type 
Dim Grid as ElementGrid 
'Now read it just like we read the Header element 
 
Now to read the Data Element 
We define the Data Element as follows : 
Option Base 1 'Now all out array indexes will start from 1 not 0.  
Type ElementData 
    ID ..... 
    Size ...... 
    matrix() as Double 
End Type 
Dim Data as ElementData 
 
'Open file , read header, grid 
'After reading grid, we know the size of the data matrix 
' Set the size of the matrix using the Redim() function 
ReDim Data.matrix (Grid.nRow,nCol) 
'Now read in the arrays 
Get 1,,Data ' Simple wasnt it? 
'Close file 
 
So you can change the size of arrays dynamically using the ReDim
function.
You can use the same method for the FaultInfo section. 
 
Here's a link to a VB6 Array tutorial 
  - Basics of Arrays by Robert Klieger 
    ( http://www.geocities.com/alpha_productions2/vb_arrays.htm#Dynaming
)
    Check out the dynamic arrays section 
  - MSDN ReDim() Reference 
    ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vblr7/html/vastmReDim.asp
)
 
Also if you have the MSDN library installed, check it out. 
Whoops! Gotta go! 
Try out the above techniques and tell me how it goes. 
Happy Coding! 
:)
watergeo-ga rated this answer:4 out of 5 stars and gave an additional tip of: $1.50
The researcher provided a very complete answer following my request
for clarification.  I think I will be able to get my file read. 
THanks for the help...

-Watergeo

Comments  
Subject: Re: Visual Basic Binary file access
From: theta-ga on 03 Nov 2002 12:05 PST
 
water-geo, I am a little short on time today and so will not be able
to give a very in-depth tutorial on this matter, but i hope to make
the basics clear enough for you to solve this problem on your own. If
you still need any clarifications, i will gladly help you tomorrow.
BTW : Please specify which version of VB you are working with, in the
following example i assume you are using VB6.
-----------
First of all here are the VB6 data types you use :
Data Type          VB6 Data Type   VB7.NET Data types
32 bit Integer  -    Long        -     Integer 
64 bit double   -    Double      -     Double

Id Description : To represent a hexadecimal value in VB6, you replace
the '0x' with '&H'. So the value 0x42525344 will be represented in VB6
as &H42525344

Ok, so you can create your header element like this :
Const HEADER_ID as Long = &H42525344 
 Type ElementHeader
      Id as Long
      Size as Long
      Version as Long
 End Type 

dim Header as ElementHeader

'Open the file as shown in the answer
'While not End of file
'Read Header element as it must be the first
Get 1,,Header
if header.Id <> HEADER_ID then
  ' ERROR! First element in file is not Header Element
end if
'Close File

I hope this helped you get the idea. I am currently generating this
code off the top of my head so please forgive any syntax errors i
make.

Now to read the Data Grid :
You can define & read a grid element easily, it is a fixed length
record and the method to read it is the same as what is shown in case
of the HeaderElement.
Type ElementGrid
    Id as...
    Size as ...
    nRow as Long
    nCol as Long
    <other variables>....
End Type
Dim Grid as ElementGrid
'Now read it just like we read the Header element

Now to read the Data Element
We define the Data Element as follows :
Option Base 1 'Now all out array indexes will start from 1 not 0. 
Type ElementData
    ID .....
    Size ......
    matrix() as Double
End Type
Dim Data as ElementData

'Open file , read header, grid
'After reading grid, we know the size of the data matrix
' Set the size of the matrix using the Redim() function
ReDim Data.matrix (Grid.nRow,nCol)
'Now read in the arrays
Get 1,,Data ' Simple wasnt it?
'Close file

So you can change the size of arrays dynamically using the ReDim
function.
You can use the same method for the FaultInfo section.

Here's a link to a VB6 Array tutorial
  - Basics of Arrays by Robert Klieger
    ( http://www.geocities.com/alpha_productions2/vb_arrays.htm#Dynaming
)
    Check out the dynamic arrays section
  - MSDN ReDim() Reference
    ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vblr7/html/vastmReDim.asp
)

Also if you have the MSDN library installed, check it out.
Whoops! Gotta go!
Try out the above techniques and tell me how it goes.
Happy Coding!
:)

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy