Reading and Writing Data


Files opened for Random and Binary data use the statements Put and Get for writing and reading data. Files opened in any other mode use the Line Input, Input, Print, and Write statements for reading and writing. If no expressions are entered, a blank line is written to the file. The Write statement accepts multiple arguments to print to the file and it automatically adds delimiters as it writes . In the created file, each expression is separated by a comma. Strings are enclosed in double quotation marks, numbers are not enclosed in anything, and dates and Boolean values are enclosed between octothorpe (#) characters .

 Write #n, expressionl, expression2, expression3, ... Print #n, expression1, expression2, expression3, ... 
Note  

The character "#" has many names , including number sign, pound sign, hash, sharp, crunch, hex, grid, pigpen, tic-tac-toe, splat , crosshatch, and octothorpe, to name a few.

The Print statement does not write any useful delimiters. Instead, it writes spaces between each expression. Numbers typically use 13 spaces.

 Write #n, i, "the time # is", Now, CDbl(1.221), CBool(0) Print #n, i, "the time # is", Now, CDbl(1.221), CBool(0) 

The code above produces the text below.

 0,"the time # is",#08/29/2003 01:07:12#,1.221,#False#  0            the time # is 08/29/2003 01:07:12 1.221      False 

As its name implies, the Line Input statement reads an entire line of text, but it does not return the delimiter . Each line is delimited by either a carriage return (ASCII value 13) or a line-feed character (ASCII value 10). These two delimiters work to read lines on every operating system supported by OpenOffice.org.

 Line Input #n, stringVar     'Read an entire line but not the delimiter. 

The Input statement reads text based on the following delimiters: comma, carriage return, or line-feed characters. The Input statement can read multiple variables of differing types in a single command.

 Input #n, varl, var2, var3, ... 

The Write command adds appropriate delimiters automatically so that you can read string and numeric data into the appropriate variable types. The Input command automatically removes commas and double quotation marks from the input when these characters are used as the delimiters. See Listing 11 and Figure 5 for input examples.

click to expand
Figure 5: Input cannot read time delimited with "#".
Listing 11: ExampleInput is found in the File module in this chapter's source code files as SC07.sxw.
start example
 Sub ExampleInput   Dim sFileName As String   Dim n As Integer   Dim t As String, d As Double, s As String   sFileName = ConvertToURL(CurDir) & "/delme.txt"   n = FreeFile()   Open sFileName For Output Access Read Write As #n   Write #n, 1.33, Now, "I am a string"   Seek(n, 1)   Input #n, d, t, s   close #n   Kill(sFileName)   s = "string (" & s & ")" & CHR$(10) &_       "number (" & d & ")" & CHR$(10) &_       "time (" & t & ") <== read as a string" & CHR$(10)   MsgBox s, 0, "Example Input" End Sub 
end example
 

Unfortunately, the delimiters produced by the Write statement are not supported by the Input statement. Numbers and simple strings read with no problems. Date and Boolean values delimited with the # character, however, fail. These values must be read into string variables and then parsed.

Do not use the Input statement if you do not have a lot of control over the input text file. Double-quotation marks and commas in text strings are assumed to be text delimiters. The end result is that the text is not properly parsed when it is read. If your input data may contain these characters, use the Line Input command and then manually parse the text. If you must read the carriage return or line-feed characters, the file should be read as a binary file.

A binary file is a random file with a block length of zero. Use the Put statement to write random and binary files. The simplest case involves putting a simple variable directly to the file.

 int_var = 4 : long_var = 2 Put #n,,int_var    '04 00       (two bytes written) Put #n,,long_var   '02 00 00 00 (four bytes written) 

The first argument is the file number and the third argument is the variable or data to write. The second argument is the position in the file where the date should be written. If you omit the position, as shown in the example, you must still include the comma.

 Put #n,,variable             'Write to the next record or byte position Put #n, position, variable   'Specify the next record or byte position 

Random files assume that the position identifies a record number. Binary files assume that the position identifies an absolute byte position. If the position is not specified, the data is written at the current file pointer, which is advanced with the data that is written.

If the data variable is a Variant, an integer identifying the data type precedes the data. This integer is the same integer returned by the VarType function, to be detailed later.

 v = 4            'A Variant variable Put #n,,v        '02 00 04 00  (first two bytes says type is 2) Put #n,,4        '02 00 04 00  (first two bytes says type is 2) Put #n,,CInt(4)  '02 00 04 00  (first two bytes says type is 2) 

A string stored as a Variant includes the VarType if it is "Put" to a file that was opened as any type other than Binary. When an array is Put to a file, each element of the array is written. If the array contains a String Variant, it includes the VarType even if the file type is Binary. When Put places a string as a Variant, it actually writes the VarType, the string length, and then the string.

 v() = Array("ABCD") 'ASCII in hexadecimal is 41 42 43 44 Put #n,,v()         '08 00 04 00 41 42 43 44 (08 00 = type) (04 00 = length) 

When data is Put to a file, the current file pointer is saved and then all of the data is written. If a non-zero block length is used, the file pointer is positioned one block length past the saved file position regardless of how much data was written. For example, if the block length is 32 and the current file position is 64, the file pointer is positioned to byte 96 after the data is written. If more than 32 bytes are written, part of the next record is overwritten. If fewer than 32 bytes are written, then the previous data is left unchanged. Because of this, some people initialize every record that will be written when the file is created. Numeric values are usually initialized to zero, and string values are usually initialized to spaces.

On the other hand, even though I don't recommend it, you can use the Put statement with a file opened in a sequential mode. Likewise, you can use the Write, Line Input, and Input statements for files opened in Binary or Random mode. The actual bytes written for writing methods used for files of the "wrong" file structure are not documented, and I had difficulty understanding the output. I finally read the source code to determine what is written in each case, but undocumented behavior determined in this way should not be assumed to be stable, reliable behavior for OOo Basic. If you want to use these methods for other file structures than those documented, I recommend that you test the output for your specific data. When a piece of data is written to a file, the specific context is used to determine what to write. See Table 11 .

Table 11: Summary of what the Put statement writes.

Type

Bytes

Comment

Boolean

1

OOo Basic stores a Boolean in an integer. The True value has all of the bits set, which incorrectly cast down to one byte, causing a run-time error. False writes with no problem.

Byte

3

Although the byte variable uses only one byte when writing the data, byte variables are supported only when stored in a Variant, so the data is preceded by two bytes of type information.

Currency

8

Internally stored as a Double.

Date

8

Internally stored as a Double.

Double

8

 

Integer

2

 

Long

4

Object

Error

Run-time error: Only the basic types are supported.

Single

4

 

String

Len(s)

Each character is one byte. Characters with an ASCII value larger than 255 are written with incomplete data. In Binary mode, the Put statement will not write characters with an ASCII value of zero. This is written fine in Random mode and the string is preceded by the string length.

Variant

Varies

Two bytes of type information are written, followed by the data. A string also includes the length of the string in two bytes.

Empty

4

An empty Variant variable writes two bytes of type information indicating an integer value, and then it writes two bytes with zeros.

Null

Error

Only an object can contain the value Null, and the Put statement does not work with objects.

Compatibility  

OOo Basic only supports using Get and Put with the standard data types.

Bug  

The Put statement cannot write a Boolean with a True value, and it doesn't properly write strings with Unicode values greater than 255.

Use Get to read Binary data and Random files. The syntax for the Get statement is similar to the Put statement.

 Get #n,,variable              'Read from next record or byte position Get #n, position, variable    'Specify the next record or byte position 

If the argument to the Get statement is a Variant, the type information is always read, regardless of the context. When a string is read, it is assumed to be preceded by an integer that contains the length of the string. This required string length is not written automatically to binary files but it is to random files. Listing 12 shows an example of reading and writing a binary file. Also see Figure 6 .


Figure 6: Use Get and Put to read and write binary files.
Bug  

As of OOo version 1.1.1, the Get statement fails for binary files if the position is not provided.

Lising 12: ExampleReadWriteBinaryFile is found in the File module in this chapter's source code files as SC07.sxw.
start example
 Sub ExampleReadWriteBinaryFile   Dim sFileName As String 'File name from which to read and write   Dim n As Integer        'File number to use   Dim i As Integer        'Scrap Integer variable   Dim 1 As Long           'Scrap Long variable   Dim s As String         'Scrap String variable   Dim s2 As String        'Another scrap String variable   Dim v                   'Scrap Variant variable   sFileName = ConvertToURL(CurDir) & "/delme.txt"   n = FreeFile()   Open sFileName For Binary As #n   i = 10  : Put #n,,i      '0A 00   i = 255 : Put #n,,i      'FF 00   i = -2  : Put #n,,i      'FE FF   1 = 10  : Put #n,,l  '  0A 00 00 00   1 = 255 : Put #n,,l      'FF 00 00 00   1 = -2  : Put #n,,1      'FE FF FF FF   REM Put string data, precede it with a length   i = 8   : Put #n,,i      '08 00 (about to put eight characters to the file)   s = "ABCD"   Put #n,,s                '41 42 43 44 (ASCII for ABCD)   Put #n,,s                '41 42 43 44 (ASCII for ABCD) REM Put data contained in a Variant Put #n,,CInt(10)         '02 00 OA 00 i = -2 : Put #n,,CInt(i) '02 00 FE FF       (Functions return a Variant) Put #n,,CLng(255)        '03 00 FF 00 00 00 (Functions return a Variant) v = 255 : Put #n,,v      '02 00 FF 00       (This IS a Variant) v = "ABCD" : Put #n,,v   '41 42 43 44       (Not in an array) v = Array(255, "ABCDE")  'The string contains type information and length Put #n,,v()              '02 00 FF 00 08 00 05 00 41 42 43 44 45 close #n REM now, read the file. s = "" n = FreeFile() Open sFileName For Binary Access Read As #n Get #n,  1, i  : s = s & "Read Integer " & i & CHR$(10) Get #n,  3, i  : s = s & "Read Integer " & i & CHR$(10) Get #n,  5, i  : s = s & "Read Integer " & i & CHR$(10) Get #n,  7, 1  : s = s & "Read Long " & 1 & CHR$(10) Get #n, 11, 1  : s = s & "Read Long " & 1 & CHR$(10) Get #n, 15, 1  : s = s & "Read Long " & 1 & CHR$(10) Get #n, 19, s2 : s = s & "Read String " & s2 & CHR$(10) close #n MsgBox s, 0, "Read Write Binary File" End Sub 
end example
 

Random files are usually used to store a user -defined data type, but this is not supported in OOo Basic; use "Open FileName For Random" to open a file for random access. The code in Listing 13 gwrites numerous types and sizes of data to the file with a block length of 8. If the Put statement had no bugs , then after writing the first block, the file pointer would be positioned to the second block for writing. It is instead positioned to the end of the file. To avoid this bug, explicitly include the position to write in the statement. If the position points to a position beyond the end of the file, the file pointer is moved to the end of the file. This is the primary reason why the code in Listing 13 initializes the file to all zeros before starting; the file is initialized with locations for the subsequent operations. Notice that the string includes the string length before the text when it is Put to the file. The output is essentially the same as Listing 12 shown in Figure 6.

Lising 13: ExampleReadWriteRandomFile is found in the File module in this chapter's source code files as SC07.sxw.
start example
 Sub ExampleReadWriteRandomFile   Dim sFileName As String 'File name from which to read and write   Dim n As Integer        'File number to use   Dim i As Integer        'Scrap Integer variable   Dim 1 As Long           'Scrap Long variable   Dim s As String         'Scrap String variable   Dim s2 As String        'Another scrap String variable   sFileName = ConvertToURL(CurDir) & "/delme.txt"   REM Now the file is initialized so it can be used!   REM Must use Access Read so that the file is not created new   REM I cannot write this as a binary file because then ASCII   REM zeros are not written.   n = FreeFile()   Open sFileName For Random As #n Len = 8   REM First, create a file with all zeros with enough room   REM for 20 8-byte records.   s = String(8 * 20-2, 0)  'String has 158 characters with ASCII value 0   Put #n,l,s               'Written as Random so Len(s) is written first   i = 0 : Put #n,l,i       'Write over the length with zeros.   REM Now write the data   i = 10  : Put #n,l,i      '0A 00   i = 255 : Put #n,2,i      'FF 00   i = -2  : Put #n,3,i      'FE FF   1 = 10  : Put #n,4,l      'OA 00 00 00   1 = 255 : Put #n,5,l      'FF 00 00 00   1 = -2  : Put #n,6,l      'FE FF FF FF   REM Put string data, precede it with a length (integer value) automatically   s = "ABCD" : Put #n,7,s  '04 00 41 42 43 44 (Length, then ASCII for ABCD) close #n   REM Now read the file.   s = ""   n = FreeFile()   Open sFileName For Random Access Read As #n Len=8   Get #n, 1, i  : s = s & "Read Integer " & i & CHR$(10)   Get #n, 2, i  : s = s & "Read Integer " & i & CHR$(10)   Get #n, 3, i  : s = s & "Read Integer " & i & CHR$(10)   Get #n, 4, 1  : s = s & "Read Long " & 1 & CHR$(10)   Get #n, 5, l  : s = s & "Read Long " & 1 & CHR$(10)   Get #n, 6, l  : s = s & "Read Long "& l & CHR$(10)   Get #n, 7, s2 : s = s & "Read String " & s2 & CHR$(10)   close #n   MsgBox s, 0, "Read Write Binary File" End Sub 
end example
 



OpenOffice.org Macros Explained
OpenOffice.org Macros Explained
ISBN: 1930919514
EAN: 2147483647
Year: 2004
Pages: 203

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net