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

10.3.4. Чтение строки из файла прямого доступа

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

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

  2. Вызвать метод Read() для чтения байтового массива byData из файла;

  3. Превратить массив byData в символьный массив char[], используя метод GetChars() объекта Decoder.

  4. Превратить массив char[] в строку.

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

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

Листинг 10.11. Чтение строки из файла через FileStream

static void Main(string[] args)

{

byte[] byData;

char[] charData;

try

{

FileStream aFile =

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

long n = aFile.Length;

byData = new byte[n];

charData = new Char[n/2];

aFile.Seek(0, SeekOrigin.Begin);

aFile.Read(byData,0,Convert.ToInt32(n));

}

catch(IOException e)

{

Console.WriteLine("Error IO!");

Console.WriteLine(e.ToString());

Console.ReadKey();

return;

}

Decoder d = Encoding.Unicode.GetDecoder() ;

d.GetChars(byData,0,byData.Length,charData, 0);

Console.WriteLine(charData);

Console.ReadKey();

}

Для преобразования других типов данных в байтовый массив предназначен метод GetBytes() класса BitConverter, который содержит переопределение этого метода для всех простых типов:

double x = 1.2;

byte[] byByte = BitConverter.GetBytes(x);

Для обратного преобразования служат многочисленные методы типа:

x = BitConverter.ToDouble(byByte,0);

Копирование и вставка:

Array.Copy(source, indsour, dest, inddest, len);

10.3.5. Запись и чтение массива

Все статические данные можно записывать и читать двумя способами: через поток класса FileStream и через потоки классов BinaryWriter/BinaryReader. Рассмотрим пример записи чтения массива arr[]:

double[] arr = {1, 2, 3};

Вариант записи 1. Запись через FileStream. Подготовим массив byData[] и запишем его:

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

byte[] byData =

new byte[arr.Length*sizeof(double)];

FileStream aFile = new FileStream("Temp.dat",

FileMode.Create);

int ofs = 0;

for (int i = 0; i < arr.Length; i++)

{

byte[] temp = BitConverter.GetBytes(arr[i]);

for (int j = 0; j < temp.Length; j++ )

byData[ofs+j] = temp[j];

ofs += temp.Length;

}

aFile.Seek(0, SeekOrigin.Begin);

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

f.Close();

Вариант записи 2. Запись через BinaryWriter. Методом Write(arr[i]) в цикле запишем все элементы массива.

Листинг 10.13. Запись массива в файл через BinaryWriter

FileStream aFile = new FileStream("Temp1.dat",

FileMode.Create);

BinaryWriter f = new BinaryWriter(aFile);

for (int i = 0; i < arr.Length; i++ )

f.Write(arr[i]);

f.Close();

aFile.Close();

И первый и второй варианты создают одинаковые файлы длиной 24 байта.

Эти файлы можно читать двумя способами.

Вариант чтения 1. Чтение через FileStream. Сначала подготовим массив byData[], методом aFile.Read() прочитаем в него данные. Затем в цикле методом BitConverter.ToDouble(byData, ofs) расстащим по элементам массива.

Листинг 10.14. Чтение массива из файла через FileStream

byte[] byData;

FileStream aFile =

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

aFile.Seek(0, SeekOrigin.Begin);

aFile.Seek(0, SeekOrigin.Begin);

long L = aFile.Length;

byData = new byte[L];

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

int n = byData.Length/sizeof(double);

arr = new double[n];

int ofs = 0;

for (int i = 0; i < n; i++)

{

arr[i] = BitConverter.ToDouble(byData, ofs);

ofs += sizeof(double);

}

aFile.Close();

Вариант чтения 2. Чтение через BinaryReader. Назначим длину массива arr[] и в цикле методом ReadDouble() прочитаем все значения элемента массива.

Листинг 10.15. Чтение массива из файла через BinaryReader

FileStream aFile =

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

BinaryReader f = new BinaryReader(aFile);

long L = aFile.Length;

arr = new double[L / sizeof(double)];

for (int i = 0; i < arr.Length; i++)

arr[i] = f.ReadDouble();

f.Close();

aFile.Close();

И первый, и второй вариант чтения дают одинаковые результаты.

Заметим, что создаются файлы прямого доступа. Если, например, необходимо прочитать первую запись, в которой находится число 2, то необходимо выполнить следующие действия при использовании потока BinaryReader:

aFile.Seek(sizeof(double),SeekOrigin.Begin);

double x = f.ReadDouble();

или такие действия при использовании потока FileStream:

byData = new byte[sizeof(double)];

aFile.Seek(sizeof(double), SeekOrigin.Begin);

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