Up to this point, we have been using sequential files, which are files that are accessed in a strictly linear fashion, one byte after another. However, C# also allows you to access the contents of a file in random order. To do this, you will use the Seek( ) method defined by FileStream. This method allows you to set the file position indicator (also called the file pointer) to any point within a file.
The method Seek( ) is shown here:
long Seek(long newPos, SeekOrigin origin)
Here, newPos specifies the new position, in bytes, of the file pointer from the location specified by origin. The origin will be one of these values, which are defined by the SeekOrigin enumeration:
Value | Meaning |
---|---|
SeekOrigin.Begin | Seek from the beginning of the fi le. |
SeekOrigin.Current | Seek from the current location. |
SeekOrigin.End | Seek from the end of the fi le. |
After a call to Seek( ), the next read or write operation will occur at the new file position. If an error occurs while seeking, an IOException is thrown. If the underlying stream does not support position requests, a NotSupportedException is thrown. Other exceptions are possible.
Here is an example that demonstrates random access I/O. It writes the uppercase alphabet to a file and then reads it back in non-sequential order.
// Demonstrate random access. using System; using System.IO; class RandomAccessDemo { public static void Main() { FileStream f; char ch; try { f = new FileStream("random.dat", FileMode.Create); } catch(IOException exc) { Console.WriteLine(exc.Message); return ; } // Write the alphabet. for(int i=0; i < 26; i++) { try { f.WriteByte((byte)('A'+i)); } catch(IOException exc) { Console.WriteLine(exc.Message); return ; } } try { // Now, read back specific values f.Seek(0, SeekOrigin.Begin); // seek to first byte ch = (char) f.ReadByte(); Console.WriteLine("First value is " + ch); f.Seek(1, SeekOrigin.Begin); // seek to second byte ch = (char) f.ReadByte(); Console.WriteLine("Second value is " + ch); f.Seek(4, SeekOrigin.Begin); // seek to 5th byte ch = (char) f.ReadByte(); Console.WriteLine("Fifth value is " + ch); Console.WriteLine(); // Now, read every other value. Console.WriteLine("Here is every other value: "); for(int i=0; i < 26; i += 2) { f.Seek(i, SeekOrigin.Begin); // seek to ith double ch = (char) f.ReadByte(); Console.Write(ch + " "); } } catch(IOException exc) { Console.WriteLine(exc.Message); } Console.WriteLine(); f.Close(); } }
The output from the program is shown here:
First value is A Second value is B Fifth value is E Here is every other value: A C E G I K M O Q S U W Y