Двоичные файлы хранят данные в том же виде, в котором они представлены в оперативной памяти, то есть во внутренней форме представления. Двоичные файлы применяются не для просмотра их человеком, а для использования в программах. Выходной поток BinaryWriter поддерживает произвольный доступ, то есть имеется возможность выполнять запись в произвольную позицию двоичного файла. Двоичный файл открывается на основе базового потока, в качестве которого чаще всего используется поток FileStream. Входной двоичный поток содержит перегруженные методы чтения для всех простых встроенных типов данных. Основные методы двоичных потоков приведены в табл. 11.8 и 11.9.
Таблица 11.8. Наиболее важные элементы класса BinaryWriter
Элемент Описание
BaseStream Базовый поток, с которым работает объект BinaryWriter
Close Закрыть поток
Flush Очистить буфер
Seek Установить позицию в текущем потоке
Write Записать значение в текущий поток
Таблица 11.9. Наиболее важные элементы класса BinaryReader
Элемент Описание
BaseStream Базовый поток, с которым работает объект BinaryReader
Close Закрыть поток
PeekChar Возвратить следующий символ без перемещения внутреннего указателя в
потоке
Read Считать поток байтов или символов и сохранить в массиве, передаваемом
как входной параметр
ReadXXXX Считать из потока данные определенного типа (например, ReadBoolean,
ReadByte, ReadInt32 и т. д.)
В листинге 11.7 приведен пример формирования двоичного файла. В файл записывается последовательность вещественных чисел, а затем для демонстрации произвольного доступа третье число заменяется числом 8888.
Листинг 11.7. Формирование двоичного файла
using System;
using System.IO;
namespace ConsoleApplication1
{
class Class1
{
static void Main()
{
try
{
BinaryWriter fout = new BinaryWriter(
new FileStream(@"D:\C#\binary", FiIeMode.Create));
double d = 0; while (d < 4)
{
fout.Write(d);
d += 0.33;
}
fout.Seek(16.SeekOrigin.Begin); // второй элемент файла
fout.Write(8888d);
fout.Close();
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message); return;
}
}
}
}
При создании двоичного потока в него передается объект базового потока. При установке указателя текущей позиции в файле учитывается длина каждого значения типа double — 8 байт.
Попытка просмотра сформированного программой файла в текстовом редакторе весьма медитативная, но не информативная, поэтому в листинге 11.8 приводится программа, которая с помощью экземпляра BinaryReader считывает содержимое файла в массив вещественных чисел, а затем выводит этот массив на экран. При чтении принимается во внимание тот факт, что метод ReadDouble при обнаружении конца файла генерирует исключение EndOfStreamException. Поскольку в данном случае это не ошибка, тело обработчика исключений пустое.
Листинг 11.8. Считывание двоичного файла
using System;
using System.IO;
namespace ConsoleApplication1
{
class Class1
{
static void Main()
{
try
{
FileStream f =
new FileStream(@"D:\C#\binary", FileMode.Open);
BinaryReader fin = new BinaryReader(f);
long n = f.Length / 8; // количество чисел в файле
double[] x = new double[n];
long i = 0; try
{
while (true) x[i++] = fin.ReadDouble(); // чтение
}
catch (EndOfStreamException e) { }
foreach (double d in x)
Console.Write(" " + d); // вывод
fin.Close(); f.Close();
}
catch (FileNotFoundException e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Проверьте правильность имени файла!");
return;
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return;
}
}
}
}
Результат работы программы:
0 0,33 8888 0,99 1,32 1,65 1,98 2,31 2,64 2,97 3,3 3,63 3,96