18.3 Reading from or writing to a binary file


You can use the FileStream class for reading from or writing to a binary file.

18.3.1 Creating a FileStream object

You create an instance of a FileStream object by passing in the path to the file you want to read. The FileStream class has several overloaded constructors which you can use to specify the following options:

  • file mode

  • file access

  • file share.

Table 18.5 describes these options.

Table 18.5. The available file mode, access, and share options that can be used when instantiating a FileStream

Enumeration

Description

FileMode “ how to open or create this file?

FileMode.Append

Opens a file, if it exists, for appending. Moves the file pointer to the end of the existing file, so that the original data will not be overwritten “ can only be used if file access has been set to FileAccess.Write

FileMode.CreateNew

Creates a new file if no such file exists “ if the file already exists, an IOException is thrown

FileMode.Create

Creates a new file regardless of whether it currently exists “ overwrites, the file if it exists (i.e. delete existing file if any) without throwing an exception

FileMode.Open

Opens an existing file “ if file does not exist, throws a FileNotFoundException

FileMode.OpenOrCreate

Opens an existing file if there is one, or creates a new file if one does not currently exist “ if writing to an existing file, writing starts from the first byte of the file and will overwrite existing bytes, but leaving the remaining bytes unchanged

FileMode.Truncate

Opens an existing file, and immediately truncates its contents

FileAccess “ how the file can be accessed by the file stream

FileAccess.Read

Opens a file for reading only

FileAccess.ReadWrite

Opens a file for reading and writing

FileAccess.Write

Opens a file for writing only

FileShare “ how the file can be shared by other processes

FileShare.None

File is not to be shared by another process until it is closed

FileShare.Read

File can be opened by another process for reading only

FileShare.ReadWrite

File can be opened by another process for reading and writing

FileShare.Write

File can be opened by another process for writing only

There are three useful constructors which you can use for FileStream .

  • public FileStream (string path, int fileMode) ;

  • public FileStream (string path, int fileMode, int fileAccess) ;

  • public FileStream (string path, int fileMode, int fileAccess, int fileShare) ;

For example, the following statement:

 FileStream fs = new   FileStream("c:\expt\loveletter.dat",               FileMode.OpenOrCreate); 

creates a new file under the specified name if it does not exist, or opens it if it already exists. The default file access is ReadWrite , and the default file share is Read .

The following statement:

 FileStream fs = new   FileStream("c:\expt\loveletter.dat",              FileMode.Create,              FileAccess.Write,              FileShare.None); 

creates a new file for writing only. This file cannot be shared by another process until it has been closed. If the file already exists, it will be overwritten.

18.3.2 Reading from a FileStream object

With the FileStream object created, you can use either of the following methods for reading data from the stream:

  • public override int ReadByte ()

  • public override int Read (in byte[] array, int offset, int count)

ReadByte() reads a single byte from the stream, casts it into an int , and returns an int . It returns -1 when the end of the stream has been reached.

The following statements open a stream and read in data one byte at a time.

 1:  using System;  2:  using System.IO;  3:  4:  public class TestClass{  5:  6:    public static void Main(){  7:      FileStream fs = new FileStream  8:        ("c:\expt\loveletter.txt",  9:          FileMode.Open, 10:          FileAccess.Read); 11: 12:      int i=0; 13:      while (i>-1){ 14:        i =  fs.ReadByte();  15:        Console.Write(i+","); 16:      } 17:      fs.Close(); 18:    } 19:  } 

Output: [5]

[5] The output shows the contents of the loveletter.txt file in my c:\expt folder. Of course, the output will differ if you put different stuff into yours!

[View full width]
 
[View full width]
c:\expt>test 68,101,97,114,32,74,117,108,105,101,116,44,13,10,73,32,121,101,97,114,110,32,102,111,114 graphics/ccc.gif ,32,117,33,13,10,89,111,117,114,32,82,111,109,101,111,13,10,-1,

A FileNotFoundException is thrown if my loveletter.txt doesn't already exist in c:\expt . If there is no expt directory in c:\ , a DirectoryNotFoundException is thrown instead. The integral equivalents of the characters are shown ( 68 D , 101 e , etc.). Of course, you can also explicitly cast the int s into char values if you are reading a text file. [6]

[6] If you are reading/writing a text file, use StreamReader and StreamWriter instead of FileStream . These classes have more convenient methods specially tailored for interacting with text files.

Read() gives you more control than ReadByte() . Read() takes in:

  • a byte array which will be populated ;

  • a specified number of bytes from the stream into a byte array; and

  • the array's index to start the population.

It returns the number of bytes actually read (this may differ from the number of bytes specified to be read, and is zero if the end of stream has been reached).

Let's look at an example. I have replaced the Main method of the code above with the following lines:

 12:  byte []byteArray = new byte[50]; 13:  int noBytesRead  =  fs.Read(byteArray,5,20);  14: 15:  Console.WriteLine("noBytesRead: "+noBytesRead); 16:  // display array contents 17:  for (int i=0; i<50; i++) 18:    Console.Write(byteArray[i] + ","); 

Output:

 c:\expt>test noBytesRead: 20 0,0,0,0,0,68,101,97,114,32,74,117,108,105,101,116,44,13,10,73, 32,121,101,97,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0, 

Line 13 instructs that the first 20 bytes are to be read from loveletter.txt into byteArray 's sixth slot ( byteArray[5] ). The next time a Read or ReadByte is called on fs , reading carries on from the 21 st byte in the file.

18.3.3 Writing to a FileStream object

With the FileStream object created, use either of the following methods to write data to the stream:

  • public override void WriteByte(byte value)

  • public override void Write(byte[] array, int offset, int count)

WriteByte simply takes in a byte and writes it to the FileStream object.

 1:  using System;  2:  using System.I/O;  3:  4:  public class TestClass{  5:  6:    public static void Main(){  7:      FileStream fs = new FileStream  8:        ("c:\expt\alphabet.txt",  9:          FileMode.Create, 10:          FileAccess.Write); 11: 12:      for (byte i=65; i<91; i++) 13:  fs.WriteByte(i);  14: 15:      fs.Close(); 16:    } 17:  } 

Contents of alphabet.txt :

 c:\expt>type alphabet.txt ABCDEFGHIJKLMNOPQRSTUVWXYZ 

Lines 12 “ 13 loops through 26 times and writes the alphabet ( 65 A , 66 B , etc.) to alphabet.txt .

Write() takes in:

  • a byte array which contains the bytes to write in;

  • the array offset (which element in the array do we start with?); and

  • the count (the number of bytes to write).

Lines 12+ above have been modified to use Write instead of WriteByte :

 12:      byte []array = {65,66,67,68,69,70,71,72,73,74}; 13:  fs.Write (array, 2, 5);  14: 15:      fs.Close(); 16:    } 17:  } 

Contents of alphabet.txt :

 c:\expt>type alphabet.txt CDEFG 

Line 13 says to take five bytes from array starting from a rray[2] , and write these into the FileStream object. array[2] is 67 ( 67 C ).

18.3.3 Closing a FileStream object

Good developers close their files after use:

 fs.Close(); 

You have already seen it in previous code examples.



From Java to C#. A Developers Guide
From Java to C#: A Developers Guide
ISBN: 0321136225
EAN: 2147483647
Year: 2003
Pages: 221
Authors: Heng Ngee Mok

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