TheDeveloperBlog.com

Home | Contact Us

C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML

C# Seek File Examples: ReadBytes

This C# article demonstrates the Seek method on streams. It requires System.IO.

Seek locates a position in a file.

It allows data to be read from a binary file at a certain part. For example, we can read 20,000 bytes from any part of a file. This is useful for certain file formats—particularly binary ones.

Example. To begin our tutorial, we use the Seek method. From databases, you know that Seek is the term for when the data can be instantly retrieved, with an index. Therefore, Seek should be fast.

Here: This example gets the 50000th byte to the 51999th byte and iterates through them.

Note: The BinaryReader class is used. The program opens the binary file with BinaryReader here. It uses the "deves.bin" file.

File.Open

C# program that seeks in Main method

using System;
using System.IO;

class Program
{
    static void Main()
    {
	// 1.
	// Open as binary file.
	using (BinaryReader b = new BinaryReader(File.Open("deves.bin",
							   FileMode.Open)))
	{
	    // 2.
	    // Important variables:
	    int length = (int)b.BaseStream.Length;
	    int pos = 50000;
	    int required = 2000;
	    int count = 0;

	    // 3.
	    // Seek the required index.
	    b.BaseStream.Seek(pos, SeekOrigin.Begin);

	    // 4.
	    // Slow loop through the bytes.
	    while (pos < length && count < required)
	    {
		byte y = b.ReadByte();
		// 5.
		// Increment the variables.
		pos++;
		count++;
	    }
	}
    }
}

Variables used in program. Length is the entire length of the file we are reading from. Pos is the index we want to start reading from. Required is the number of bytes we want to read. Count is the number of bytes we have read.

Seek: We call Seek on the BaseStream and move the position to 50000 bytes. It looks through each byte.

The above code can slow down IO. It apparently requires each byte to be read separately off the disk. By using arrays, we can improve performance by several times. Next, we look at the version that uses arrays.

Example 2. We next use the Seek method with arrays of bytes. There are two useful methods you can call to read in an array of bytes. They are Read and ReadBytes. Below we see ReadBytes, but if you need to reuse your buffer, use Read.

C# program that uses Seek and ReadBytes

using System;
using System.IO;

class Program
{
    static void Main()
    {
	// 1.
	// Open file with a BinaryReader.
	using (BinaryReader b = new BinaryReader(File.Open("deves.bin",
							   FileMode.Open)))
	{
	    // 2.
	    // Variables for our position.
	    int pos = 50000;
	    int required = 2000;

	    // 3.
	    // Seek to our required position.
	    b.BaseStream.Seek(pos, SeekOrigin.Begin);

	    // 4.
	    // Read the next 2000 bytes.
	    byte[] by = b.ReadBytes(required);
	}
    }
}

The example opens the same binary file. We start at the same index in the file as the previous example (the 50000th byte). BinaryReader itself doesn't provide Seek, but you can use BaseStream with no damage.

And: It calls ReadBytes. This reads in the 2000 required bytes. These are stored in the byte array.

Note: If there aren't enough bytes left, the ReadBytes method does not throw exceptions.

Reusing byte[] buffers. The above code could be changed so you can provide your own buffer. This could cut down on memory usage and memory pressure in some situations. In a performance-sensitive application, this makes sense.

Discussion. Here we look at two Read methods available on the BinaryReader class. They both will store the result in an array but with the Read method you can provide your own buffer, which can reduce memory usage in some scenarios.

BinaryReader.ReadBytes: Reads count bytes from the current stream into a byte array and advances the current position by count bytes.

ReadBytes: MSDN

BinaryReader.Read: Reads count bytes from the stream with index as the starting point in the byte array.

Read: MSDN

Benchmarks. Here we compare the performance benchmarks of the first example shown in this article (which uses single byte reads) and the second example in this article (which uses arrays). The array example is much faster.

Note: This may occur because Windows doesn't buffer the single byte reads well. Also, there are different layers of code here.

Benchmark notes for Seek

Bytes read: 20000
File size: 2.94 MB
Start position: Inclusive random number
Compilation: Release
Iterations: 10000

Seek benchmark results

Read one byte: 2574 ms
Read array:     671 ms

Summary. We used the Seek method on the BinaryReader and FileStream classes. The article showed the performance of using seeking with BinaryReader and FileStream. Using the array read method is far faster than using single bytes.

Finally: In my test with a three megabyte file, the amount of time executing the Seek wasn't significant.


Related Links

Adjectives Ado Ai Android Angular Antonyms Apache Articles Asp Autocad Automata Aws Azure Basic Binary Bitcoin Blockchain C Cassandra Change Coa Computer Control Cpp Create Creating C-Sharp Cyber Daa Data Dbms Deletion Devops Difference Discrete Es6 Ethical Examples Features Firebase Flutter Fs Git Go Hbase History Hive Hiveql How Html Idioms Insertion Installing Ios Java Joomla Js Kafka Kali Laravel Logical Machine Matlab Matrix Mongodb Mysql One Opencv Oracle Ordering Os Pandas Php Pig Pl Postgresql Powershell Prepositions Program Python React Ruby Scala Selecting Selenium Sentence Seo Sharepoint Software Spellings Spotting Spring Sql Sqlite Sqoop Svn Swift Synonyms Talend Testng Types Uml Unity Vbnet Verbal Webdriver What Wpf