Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция 10 Бинарные файлы.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
165.81 Кб
Скачать

10.3. Файлы прямого доступа

10.3.1. Запись в двоичный файл

Запись в двоичный файл похожа на запись в текстовый файл:

  1. создать поток FileStream;

  2. создать объект BinaryWriter, связав его с потоком;

  3. методом Write(), имеющим 17 перегруженных вариантов, записать данные;

  4. методом Close(), освободив промежуточный буфер, закрыть файл;

  5. методом Close(), закрыть файловый поток.

Пример 10.3. Записать в двоичный файл 3 значения: целое, вещественное и логическое (папка Ch10\Запись BinaryWriter).

Листинг 10.8. Запись в бинарный файл

static void Main(string[] args)

{

int a = 12;

double r = 12;

FileStream aFile =

new FileStream("Temp.dat",FileMode.Create);

BinaryWriter f = new BinaryWriter(aFile);

f.Write(a);

f.Write(false);

f.Write(r);

a = 15; r = 1;

f.Write(a);

f.Write(r);

f.Write(true);

f.Close();

aFile.Close();

}

Файл Temp.dat будет создан в папке ..\Debug.

10.3.2. Чтение двоичного файла

Запись в двоичный файл похожа на запись в текстовый файл:

  1. Создать поток FileStream;

  2. создать объект BinaryReader, связав его с потоком;

  3. одним из методов ReadXXX(), имеющим 17 вариантов, прочитать данные;

  4. Методом Close(), освободив промежуточный буфер, закрыть файл;

  5. Методом Close(), закрыть файловый поток.

Среди методов ReadXXX() есть: Read(), ReadBoolean(), ReadByte(), ReadDouble(), ReadInt32(), ReadString() и т.д.

Пример 10.4. Прочитать из двоичного файла 3 значения: целое, вещественное и логическое (папка Ch10\Чтение BinaryReader).

Листинг 10.9. Создание статического массива и вывод его элементов

static void Main(string[] args)

{

int a;

double r;

bool b;

FileStream aFile =

new FileStream("Temp.dat", FileMode.Open);

BinaryReader f = new BinaryReader(aFile);

aFile.Seek(0, SeekOrigin.Begin);

a = f.ReadInt32();

r = f.ReadDouble();

b = f.ReadBoolean();

f.Close();

aFile.Close();

}

Файл Temp.dat должен быть в папке ..\Debug.

10.3.3. Запись строки в файл прямого доступа

Процесс записи в файл произвольного доступа очень похож:

  1. Cоздать поток FileStream;

  2. Cоздать символьный массив; простейший способ сделать это состоит в том, чтобы сначала построить байтовый массив, который планируется записать в файл.

  3. Затем используйте объект Encoder для преобразования его в байтовый массив, почти так же, как используется объект Decoder.

  4. Вызвать метод Write() для отправки массива в файл;

  5. Методом Close(), закрыть файловый поток.

Рассмотрим простой пример, демонстрирующий, как это делается.

Пример 10.5. Запись строки в файл произвольного доступа

Листинг 10.10. Запись строки в файл через FileStream

class Program

{

static void Main(string[] args)

{

byte[] byData;

char[] charData;

try

{

FileStream aFile =

new FileStream("Temp.dat",

FileMode.Create);

charData =

"Переместить 123".ToCharArray();

byData =

new byte[4*charData.Length];

Encoder e =

Encoding.Unicode.GetEncoder();

e.GetBytes(charData, 0,

charData.Length,byData, 0, true);

aFile.Seek(0, SeekOrigin.Begin);

aFile.Write(byData,0,byData.Length);

}

catch (IOException ex)

{

Console.WriteLine("Error IO!");

Console.WriteLine(ex.ToString());

Console.ReadKey();

return;

}

}

}

Это приложение открывает файл Temp.dat в каталоге ..\Debug и пишет в него строку "Переместить 123".

Следующая строка кода создает символьный массив charData[ ] с использованием статического метода ToCharArray() класса string. Поскольку все в С# является объектами, и текст "Переместить 123" — это на самом деле объект string, такие статические методы могут быть вызваны даже на строке символов:

CharData = "Переместить 123".ToCharArray();

Следующие строки показывают, как преобразовать символьный массив в байтовый массив byData[], необходимый объекту FileStream:

Encoder e = Endoding.UTF32.GetEncoder();

е.GetBytes(charData, 0, charData.Length, byData, 0, true);

Объект Encoder создается на базе кодировки Unicode. Всего у объекта есть 5 кодировок:

  1. ASCII – каждый символ порождает 1 элемент массива byData[]. Кириллица теряется.

  2. Unicode (UTF16) – каждый символ порождает 2 элемента массива byData[]. Кириллица не теряется.

  3. UTF32 – каждый символ порождает 4 элемента массива byData[]. Кириллица не теряется

  4. UTF7 – каждый символ кириллицы порождает 4 элемента массива byData[], остальные – 1. Кириллица не теряется

  5. UTF8 – каждый символ кириллицы порождает 2 элемента массива byData[], остальные – 1. Кириллица не теряется.

Метод GetBytes() преобразует символьный массив в байтовый массив. GetBytes() принимает символьный массив в качестве первого параметра (charData в рассматриваемом примере) и индекс, указывающий на начало массива, в качестве второго параметра 0 — для начала массива. Третий параметр — количество символов, подлежащих преобразованию (charData.Length — количество элементов в массиве charData). Четвертый параметр — байтовый массив, в который нужно поместить данные (byData), а пятый параметр — индекс, указывающий на начало записи в байтовом массиве 0 — для начала массива byData.

Шестой и последний параметр определяет, должен ли объект Encoder сбрасывать свое состояние после завершения работы. Это отражает тот факт, что объект Encoder запоминает место в памяти, где он остановился в байтовом массиве. Это предназначено для последовательных вызовов объекта Encoder, но бессмысленно при единственном его вызове. Финальный вызов Encoder должен установить этот параметр в true, чтобы очистить его память и освободить объект для сборки мусора.

После этого остается записать байтовый массив в FileStream, используя метод Write():

aFile.Seek(0, SeekOrigin.Begin);

aFile.Write(byData, 0, byData.Length);