Recipe 12.16. Using File-Access Methods


Problem

It seems that there are a million ways to open and edit a file using Visual Basic, and you are unsure of the differences.

Solution

How you edit a file depends on how you first open it. Visual Basic 2005 has some traditional file-editing features that are variations of what it had back in Version 1.0 of the language, and you can use some of the file-editing features provided with the .NET Framework (such as streams). Also, many objects provide options to immediately "serialize" their content to a file in an XML or similar format. This recipe documents some of the common file-editing choices available to you in Visual Basic. It does not provide full source code using each possible option. Instead, it provides an overview of the options available to you.

Discussion

Visual Basic supports two primary methods of file access:handle-based and streambased.

Handle-based file access

Visual Basic traditionally supports a handle-based method of file management. Each file opened for input or output has a generated numeric ID that is always used to reference that file. The Visual Basic FreeFile() method generates this numeric handle, and the handle is assigned before a file is ever accessed. To open an existing file, you first obtain an ID and then open the file:

 Dim fileHandle As Integer =   FreeFile( ) FileOpen(fileHandle, "C:\DataFile.dat", OpenMode.Input, _    OpenAccess.Read, OpenShare.Shared) 

There are several other functions in Visual Basic that deal with file manipulation, and all of them use the file handle returned from FreeFile(). You must continue to use the handle for all interactions with the opened file until you specifically close the file.

Care must be taken when using FreeFile(). Until you actually use a file handle to open a file, it is considered unused, and FreeFile() will keep returning it again and again because it knows it to be unused. Consider the following code:

 Dim fileHandleIn As Integer = FreeFile( ) Dim fileHandleOut As Integer = FreeFile( ) FileOpen(fileHandleIn, inputFilePath, OpenMode.Input) FileOpen(fileHandleOut, outputFilePath, OpenMode.Output) 

The problem with this code is that fileHandleIn and fileHandleOut probably contain the same numeric handle. That handle number will get used by the first FileOpen( ) call, leaving the second one to fail. The following code should be used instead:

 Dim fileHandleIn As Integer = FreeFile( ) FileOpen(fileHandleIn, inputFilePath, OpenMode.Input) Dim fileHandleOut As Integer = FreeFile( ) FileOpen(fileHandleOut, outputFilePath, OpenMode.Output) 

Handle-based files are opened in one of three modes:


Sequential

Sequential files are typically text files, and you add data to or retrieve data from these files in the form of text strings and whole text lines. The FileOpen( ) statement includes three variations of this mode through the OpenMode.Input, OpenMode. Output, and OpenMode.Append arguments, all of which are fairly self-describing. To open a file so that you can append additional data, use this statement:

 FileOpen(fileHandle, fileName, OpenMode.Append) 

If the file that you open for Output or Append does not yet exist, FileOpen( ) creates it for you, assuming that the supplied path is valid.

Additional variations of the FileOpen( ) method include additional arguments beyond the three shown above. A fourth argument to FileOpen( ), the OpenAccess argument, indicates your read/write interaction with the file. A fifth argument, OpenShare, declares whether and how you will block other users from the file while you are using it.

Once the file is open, you have a few choices as to the format of the data you will place in the file. Most of the reading and writing features for sequential files appear in pairs. The Write( ) and WriteLine( ) methods send formatted data to the output in a way that is very easy to read back in later. Each value is specifically prepared for output. For instance, date values are surrounded with # characters, and use a consistent format. When you are ready to read such data, the Input( ) method correctly "unformats" the formatted data created using Write( ) and WriteLine( ).

For more free-form management of data, use the Print( ) and PrintLine( ) functions to output character data. Later, you can use the InputString( ) or LineInput( ) functions to retrieve sections of a line or entire text lines.

If you need to line up data columns when outputting data with Print( ) and PrintLine( ), you can use the FileWidth( ), SPC( ), and TAB( ) features that Visual Basic includes to help manage such formatted output.


Binary

Binary files generally store raw binary data, such as image bitmaps, and interaction with these files often occurs through individual bytes or blocks of bytes. The OpenMode.Binary mode marks an open file as binary.

Binary data is generally written using the FilePut( ) and FilePutObject( ) methods and later read back in using the FileGet( ) and FileGetObject( ) methods. There is no concept of "lines" in a binary file; data is written out in chunks, with nothing to delimit the chunks unless you specifically output a delimiter.


Random

Random file access involves records and structures. Positioning within random files is generally done via record number, not by byte or character position. The OpenMode.Random mode marks an open file as random. When using random files, you can add a sixth argument to the FileOpen( ) method that indicates the common length of every record.

As with binary files, random files use the FilePut( ) and FilePutObject( ) methods for output and the FileGet( ) and FileGetObject( ) methods for input. Each object or structure written out to the file is considered to be a unit consistent with the specified record length (if used). When you later read the contents of a random file back in, you must use the same record length to ensure a match between the output and input data boundaries.

Random files allow specific records or sections of the file to be locked and unlocked using the Lock( ) and Unlock( ) methods. You can determine your current position in the file (by record number) using the Loc( ) function.

There are a few functions that work with all file modes. The FileClose() and Reset() methods let you close a single file and all open files, respectively. The EOF() function indicates whether you have reached the end of a file that you are scanning, although it isn't always reliable with random files. Finally, the Seek() function and Seek() method (two features with the same name) let you determine and move the current position marker within an open file.

Stream-based file access

While Visual Basic continues to support handle-based file access for reasons of compatibility, streams are the preferred file access method in .NET. Streams are defined through the System.IO.Stream class and through several derived classes that enhance that base class (such as providing a stream focused on network data).

Streams provide three basic operations: Read() (and its variations), Write() (with variations), and Seek(). Not all streams support these basic features. You can use the CanRead(), CanWrite(), and CanSeek() methods to determine their availability.

Streams are useful because they let you manage a file at a granular level, through the individual bytes. However, it isn't always convenient to constantly convert non-Byte data back and forth to Bytes. To make file reads and writes easier, the System.IO namespace also includes stream readers and stream writers as separate classes. These distinct classes get wrapped around a stream and provide start-to-finish reading or writing of a stream's content. The StreamReader class wraps a Stream object, providing simplified reading of the stream's content. For instance, the ReadLine() method returns the next line in the stream as a string:

 Dim oneLine As String Dim scanFile As New IO.StreamReader("c:\data.txt") Do While Not scanFile.EndOfStream    oneLine = scanFile.ReadLine( )    ' ----- Process the line contents here. Loop scanFile.Close( ) 

The StreamWriter class provides the opposite features, allowing you to write strings and other basic data types to a stream.

Related stream readers and writers include the StringReader and StringWriter pair (identical to the StreamReader and StreamWriter classes, but using a String as the underlying storage content instead of a Stream) and the BinaryReader and BinaryWriter classes, which provide a simplified method of reading and writing binary and core data-type content.

Some of the objects and features in the My.Computer. FileSystem object provide access to file streams. My.Computer. FileSystem.OpenTextFileReader() opens a StreamReader based on an existing file path. You can also create a new file stream using the System.IO.File.Create() method or other similar methods.

The My namespace includes a TextFieldParser object that provides simplified access to files with columnar data in either delimited columns (such as tab-delimited fields) or fixed-width fields.

For those objects that support serialization of their content to XML files, the basic transport between the object and the destination file is the Stream. Streams also appear when data needs to pass through some sort of conversion on its way to another destination. The cryptography features in the System.Security.Cryptography namespace frequently use streams during encryption and hashing operations.

See Also

Other recipes in this chapter provide specific examples using the file-processing features available to Visual Basic. Most of the recipes focus on stream-based file access because that is the preferred file-interaction method in .NET.




Visual Basic 2005 Cookbook(c) Solutions for VB 2005 Programmers
Visual Basic 2005 Cookbook: Solutions for VB 2005 Programmers (Cookbooks (OReilly))
ISBN: 0596101775
EAN: 2147483647
Year: 2006
Pages: 400

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