- •10.3. Файлы прямого доступа
- •10.3.1. Запись в двоичный файл
- •10.3.2. Чтение двоичного файла
- •Создать поток FileStream;
- •Методом Close(), освободив промежуточный буфер, закрыть файл;
- •Методом Close(), закрыть файловый поток.
- •10.3.3. Запись строки в файл прямого доступа
- •Методом Close(), закрыть файловый поток.
- •10.3.4. Чтение строки из файла прямого доступа
- •Cоздать поток FileStream;
- •Методом Close(), закрыть файловый поток.
- •10.3.5. Запись и чтение массива
- •10.3.6. Запись и чтение типизированного файла
- •10.3.7. Пример бд «Студенты»
- •10.4. Другие классы для работы с файлами
- •10.4.1. Классы File и Directory
- •10.4.2. Класс FileInfо
- •10.4.3. Класс DirectoryInfо
10.3.4. Чтение строки из файла прямого доступа
Процесс чтения строки из файла произвольного доступа:
Cоздать поток FileStream;
Вызвать метод Read() для чтения байтового массива byData из файла;
Превратить массив byData в символьный массив char[], используя метод GetChars() объекта Decoder.
Превратить массив char[] в строку.
Методом 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);
