
- •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. Файлы прямого доступа
10.3.1. Запись в двоичный файл
Запись в двоичный файл похожа на запись в текстовый файл:
создать поток FileStream;
создать объект BinaryWriter, связав его с потоком;
методом Write(), имеющим 17 перегруженных вариантов, записать данные;
методом Close(), освободив промежуточный буфер, закрыть файл;
методом 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. Чтение двоичного файла
Запись в двоичный файл похожа на запись в текстовый файл:
Создать поток FileStream;
создать объект BinaryReader, связав его с потоком;
одним из методов ReadXXX(), имеющим 17 вариантов, прочитать данные;
Методом Close(), освободив промежуточный буфер, закрыть файл;
Методом 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. Запись строки в файл прямого доступа
Процесс записи в файл произвольного доступа очень похож:
Cоздать поток FileStream;
Cоздать символьный массив; простейший способ сделать это состоит в том, чтобы сначала построить байтовый массив, который планируется записать в файл.
Затем используйте объект Encoder для преобразования его в байтовый массив, почти так же, как используется объект Decoder.
Вызвать метод Write() для отправки массива в файл;
Методом 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 кодировок:
ASCII – каждый символ порождает 1 элемент массива byData[]. Кириллица теряется.
Unicode (UTF16) – каждый символ порождает 2 элемента массива byData[]. Кириллица не теряется.
UTF32 – каждый символ порождает 4 элемента массива byData[]. Кириллица не теряется
UTF7 – каждый символ кириллицы порождает 4 элемента массива byData[], остальные – 1. Кириллица не теряется
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);