The BinaryWriter class. Working with binary files
It is recommended that you familiarize yourself with the following topics before exploring this topic:
- Stream concept. Stream architecture in C#. Basic storage streams. Streams with decorators. Adapters streams
- The BinaryReader class. Working with binary files
Contents
- 1. The BinaryWriter class. The purpose
- 2. Interaction of the BinaryWriter class with base store streams
- 3. The BinaryWriter class constructors. Creating an instance
- 4. Basic methods of BinaryWriter class
- Related topics
Search other websites:
1. The BinaryWriter class. The purpose
The BinaryWriter class is designed to write data in binary format. Data can be written to files, network, isolated storage, memory, etc. When writing strings, it is possible to specify the desired encoding. The default is UTF-8 encoding.
The class is implemented in the System.IO namespace. In order to use the capabilities of this class, you need to add the line
using System.IO;
The BinaryWriter class writes data that is represented by:
- primitive types: int, float, double and others;
- strings of type string in the specified encoding.
⇑
2. Interaction of the BinaryWriter class with base store streams
The BinaryWriter class (as well as the BinaryReader) is stream adapter. This means the following. To access a file, network, or memory, you need to use an intermediate base store class (FileStream, MemoryStream, NetworkStream, etc.).
The figure shows the interaction of the BinaryWriter class with the file storage, which corresponds to the FileStream class.
Figure. The interaction of the BinaryWriter class with the file through the FileStream class
⇑
3. The BinaryWriter class constructors. Creating an instance
The BinaryWriter class has several constructors, the most common of which are:
public BinaryWriter(Stream output) public BinaryWriter(Stream output, System.Text.Encoding encoding)
here
- output – a reference to the abstract Stream class, which is the top of the I/O class hierarchy;
- encoding – encoding system (Unicode, UTF32, UTF8 or other). The default encoding system is UTF8.
Example. In order to create an instance of the BinaryWriter class and associate it with the file “abc.bin”, you need to run the following code.
// Create a file named "abc.bin" for writing using (FileStream fs = new FileStream("abc.bin", FileMode.Create, FileAccess.Write)) { // 2. Link fs stream to bw instance: // bw -> fs -> "abc.bin" using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default)) { ... } ... }
As you can see from the example, when creating streams the using() keyword is used. This removes the need to close threads using the Close() method, since this approach automatically cleans up resources.
⇑
4. Basic methods of BinaryWriter class
4.1. The Write() method – many overloaded implementations
The main method of the BinaryWriter class is the Write() method. This method allows you to write data of all primitive (standard) types to the stream.
The method has 20 overloaded implementations, the main of which are listed below.
4.1.1. Writing single values. The overloaded Write() method. Example
To write single values, the Write() methods are used, which have the following general form
public virtual void Write(bool value) public virtual void Write(byte value) public virtual void Write(char ch) public virtual void Write(decimal value) public virtual void Write(double value) public virtual void Write(float value) public virtual void Write(int value) public virtual void Write(long value) public virtual void Write(sbyte value) public virtual void Write(short value) public virtual void Write(string value) public virtual void Write(uint value) public virtual void Write(ulong value) public virtual void Write(ushort value)
here value is the value of one of the standard (primitive) types to be written to the stream.
Example. In the example, data of different types is written to the file “data.bin” using the Write() method. This data is then read for monitoring purposes.
using System; using System.IO; using System.Text; namespace ConsoleApp10 { class Program { static void Main(string[] args) { // 1. Write data of different types to the file "data.bin" using (FileStream fs = new FileStream("data.bin", FileMode.Create)) { using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default)) { // Writing data of different types to the "data.bin" file bool b = false; // тип bool int i = 233; double x = 2.338; decimal d = 0.011199m; float f = -30.88f; // Writing bw.Write(b); // write the bool type bw.Write(i); // write the int type bw.Write(x); bw.Write(d); bw.Write(f); bw.Write(1234567890123L); // write the long number } } // 2. Reading data of different types from the "data.bin" file using (FileStream fs = new FileStream("data.bin", FileMode.Open)) { using (BinaryReader br = new BinaryReader(fs, Encoding.Default)) { // Reading data of different types bool b2 = br.ReadBoolean(); // read the bool type int i2 = br.ReadInt32(); double x2 = br.ReadDouble(); decimal d2 = br.ReadDecimal(); float f2 = br.ReadSingle(); long l2 = br.ReadInt64(); // Display the read data on the screen for control Console.WriteLine("b2 = {0}", b2); Console.WriteLine("i2 = {0}", i2); Console.WriteLine("x2 = {0:f3}", x2); // precision 3 decimal places Console.WriteLine("d2 = {0}", d2); Console.WriteLine("f2 = {0:f2}", f2); Console.WriteLine($"l2 = {l2}"); // another way to display } } } } }
The result of the program
b2 = False i2 = 233 x2 = 2.338 d2 = 0.011199 f2 = -30.88 l2 = 1234567890123
⇑
4.1.2. Writing byte arrays byte[] to the stream. Example
Writing bytes of arrays of type byte[] is useful when arrays of standard types (for example, arrays int[], double[], decimal[], etc.) need to be written to the stream. To convert from standard types to the byte[] type, it is convenient to use the capabilities of the BitConverter class.
public virtual void Write(byte[] buffer) public virtual void Write(byte[] buffer, int index, int count)
here
- buffer – memory portion from which data will be written to the stream byte by byte;
- index – the position (index) of the beginning in the buffer array, from which the stream will be written;
- count – the number of bytes to be written to the stream.
Example. In the example, using the Write() method, an array of numbers of type double[] is written to the file “array.dat”. Then this array is read and displayed for verification.
using System; using System.IO; using System.Text; namespace ConsoleApp10 { class Program { static void Main(string[] args) { // Write an array of numbers of type double[] to the file "array.bin" // 1. The source array double[] AD = { 2.88, 3.11, 4.88 }; // 2. Writing the array using (FileStream fs = new FileStream("array.bin", FileMode.Create)) { using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default)) { // Additional array of byte[] type byte[] AB; // First write the number of numbers in AD array bw.Write(AD.Length); // Loop for writing numbers of decimal[] type for (int i=0; i<AD.Length; i++) { // converting byte[] <- double AB = BitConverter.GetBytes(AD[i]); // Write double as array of byte[] bw.Write(AB, 0, AB.Length); // you can do that too //bw.Write(AB); } } } // 3. Read data from file array.bin" using (FileStream fs = new FileStream("array.bin", FileMode.Open)) { using (BinaryReader br = new BinaryReader(fs, Encoding.Default)) { // Declare additional variables double[] AD2; // The resulting array // additional array buffer byte[] B2 = new byte[sizeof(double)]; // allocate memory for B2 // Count the number of numbers first int count = br.ReadInt32(); // Allocate memory for array AD2 AD2 = new double[count]; // Read data from file as byte[] and convert it to double for (int i = 0; i < AD2.Length; i++) { // Read data into buffer as byte[] br.Read(B2); // convert byte[] -> double AD2[i] = BitConverter.ToDouble(B2); } // Display AD2 for control Console.Write("AD2 = { "); foreach (double x in AD2) Console.Write($"{x} "); Console.WriteLine(" }"); } } } } }
The result of the program
AD2 = { 2.88 3.11 4.88 }
⇑
4.1.3. Writing character arrays char[] to a stream. Example
To write character strings as an array char[], the following two implementations of the Write() method are used:
public virtual void Write(char[] chars) public virtual void Write(char[] chars, int index, int count)
here
- chars – an array of characters to be written to the stream;
- index – the position of the first character in the chars array, starting from which you want to write data;
- count – the number of characters to read from the chars array and write to the stream.
Example. The example writes a string of type string to the file stream as a character array char[].
using System; using System.IO; using System.Text; namespace ConsoleApp10 { class Program { static void Main(string[] args) { // Write a string as an array char[] to the file "string.bin" // 1. The source string string s = "bestprog.net"; // 2. Write the string using (FileStream fs = new FileStream("string.bin", FileMode.Create)) { using (BinaryWriter bw = new BinaryWriter(fs, Encoding.Default)) { // Additional array of char[] type char[] chars; // Converting string -> char[] chars = s.ToCharArray(); // Write the number of characters in the array chars bw.Write(chars.Length); // Write array chars to the file bw.Write(chars); } } // 3. Reading data from file "string.bin" using (FileStream fs = new FileStream("string.bin", FileMode.Open)) { using (BinaryReader br = new BinaryReader(fs, Encoding.Default)) { // Declare additional variables string s2; // the resulting string // additional array-buffer char[] chars2; // Read the number of elements in file int count = br.ReadInt32(); // Read a string as an array of type char[] chars2 = br.ReadChars(count); // Convert string chars2 to string s2 = new string(chars2); // Print s2 Console.WriteLine(s2); // bestprog.net } } } } }
The result of the program
bestprog.net
⇑
4.2. The Seek() method. Example
The Seek() method sets the position in the current thread. The general form of the method is as follows:
public virtual long Seek(int offset, System.IO.SeekOrigin origin)
here
- offset – offset in bytes from the origin position;
- origin – a value indicating the starting point from which the new position should be obtained.
The value of origin is an enumeration and has the type
enum System.IO.SeekOrigin
Values from the enumeration can be as follows:
- SeekOrigin.Begin – the starting point of reference is set at the beginning of the stream (file);
- SeekOrigin.End – the starting point is set at the end of the stream (file);
- SeekOrigin.Current – the current position in the stream (file) is determined.
Example. The example demonstrates the following operations:
- write numbers to the file;
- overwriting previously recorded numbers;
- appending a number to the end of the file.
using System; using System.IO; using System.Text; namespace ConsoleApp10 { class Program { static void Main(string[] args) { // Writing numbers to the "data.bin" file and replacing them // Create a stream associated with the data.bin file: fs -> data.bin FileStream fw = new FileStream("data.bin", FileMode.Create); // Create the stream adapter bw: bw -> fs -> data.bin BinaryWriter bw = new BinaryWriter(fw, Encoding.Default); // Write the number of type int bw.Write(255); // Write the number of type double bw.Write(7.88); // Overwrite the second double with another value. bw.Seek(sizeof(int), SeekOrigin.Begin); // offset - size of int type bw.Write(8.88); // Overwrite the first int with another value bw.Seek(0, SeekOrigin.Begin); // offset 0 relative to the beginning of the stream bw.Write(77); // Append the third float to the end. bw.Seek(0, SeekOrigin.End); bw.Write(100.05f); // Close streams bw.Close(); fw.Close(); // 2. Checking // Open the file "data.bin" for reading: fr <- data.bin FileStream fr = new FileStream("data.bin", FileMode.Open); // Create the stream adapter: br <- fr <- data.bin BinaryReader br = new BinaryReader(fr, Encoding.Default); // Read the integer int d = br.ReadInt32(); // Read the double number double x = br.ReadDouble(); // Read the float number float f = br.ReadSingle(); // Print the result Console.WriteLine($"d = {d}"); // d = 77 Console.WriteLine($"x = {x}"); // x = 8.88 Console.WriteLine($"f = {f}"); // f = 100.05 // Close streams bw.Close(); fw.Close(); } } }
The result of the program
d = 77 x = 8.88 f = 100.05
⇑
4.3. The Flush() method. Example
The Flush() method is used to flush all buffers of the current writer. You can then write any buffered data to the device that you are currently allowed to write to.
In the most general case, a call to the Flush() method looks like this:
FileStream fs = new FileStream("file.dat", FileMode.Create); BinaryWriter bw = new BinaryWriter(fs, Encoding.Default); ... bw.Flush(); ... bw.Close(); fs.Close();
⇑
Related topics
- The BinaryReader class. Working with binary files
- Examples of solving tasks of reading from files and writing data to files in binary format
⇑