Binary Data File I/O
Let's say you have a financial application and you want to write native numerical types to a disk file. Rather than imposing the overhead of translating the native data into XML or some other text format, you decide to write native data to disk. This approach has advantages and disadvantages. On the plus side, the data can be written out quickly, and the same applies to reading. However, the application must know exactly what data objects have been written to disk, and in what order the data is laid out in the binary file. These considerations can make native disk data a bit brittle. However, the C# serialization mechanism uses this approach, so there are circumstances when you should use native data formats.
It's very easy to read and write binary data with C#. Listing 5 shows an example.
Listing 5Binary file I/O.
FileInfo anotherFile = new FileInfo(binFileName); BinaryWriter binaryWriter = new BinaryWriter(anotherFile.OpenWrite()); binaryWriter.Write(1234); binaryWriter.Write(45456.556); binaryWriter.Flush();
Not too much happens in Listing 5. (In fact, it's very similar to the code in Listing 3.) I create an instance of BinaryWriter and write out some native C# data. I then flush the data to ensure that it gets written to disk. This last step is optional, of course. Since the approach in this article is not to leave any files on the disk after the program runs, we don't have an opportunity to read in the data persisted in Listing 5. But it's not hard to read such data back from disk. Listing 6 provides some sample code that I added to the supplied source code.
Listing 6Reading binary data.
FileInfo anotherFile1 = null; BinaryReader binaryReader = null; anotherFile1 = new FileInfo(binFileName); binaryReader = new BinaryReader(anotherFile1.OpenRead()); Console.WriteLine("First binary object is: " + binaryReader.ReadInt32()); Console.WriteLine("Second binary object is: " + binaryReader.ReadDouble()); binaryReader.Close();
I've removed the exception-handling code from Listing 6 for simplicity. Notice the way I explicitly read back the data written out in Listing 5: I first read an Int32 and then a Double. You can see that the structure of my data is dictating the code structure. This isn't bad practiceit's just a style of development.