- •1 Классы потоков
- •1.3 Символьные классы потоков
- •2.1.2 Запись данных в консольный входной поток
- •2.2 Класс FileStream. Файловый побайтовой ввод-вывод
- •2.2.1 Открытие и закрытие файла
- •2.2.2 Считывание байт из объекта класса FileStream..
- •2.3 Файловый ввод-вывод с ориентацией на символы
- •2.3.1 Использование класса StreamWriter
- •2.3.2 Использование класса StreamReader
- •2.4 Перенаправление стандартных потоков
- •2.5 Считывание и запись двоичных данных
- •2.5.1 Класс BinaryWriter
- •Класс BinaryReader
- •Применение двоичного ввода-вывода
- •2.7 Считывание входных данных из массива и запись их в массив
- •2.9 Преобразование числовых строк во внутреннее представление
-
Класс BinaryReader
Это оболочка для байтового потока, которая управляет чтением двоичных даных. Его конструктор имеет вид – BinaryReader(Stream inputStream).
Здесь inputStream означает поток, из котоого считываются даные, чтобы выполнить чтение из файла. Могут генерироваться ИС:
ArgumentNullException- имеются null-значения.
ArgumentException- поток не открыт длч\я чтения.
В классе предусмотрены методы для считывания всех простых С#-типов (cм. таблицу):
№ |
Метод |
Орисание |
1 |
Int Read() |
Возвращает целочисленное представление следующего доступного символа из вызывающего входного потока. Приобнаружении конца файла возвращает значение -1 |
2 |
Int Read(byte[]buf, int offset, int num) |
Делает попытку прочитать num байтов в массив buf, начиная с элемента buf [offset], и возвращает количество успешно считанных байтов |
3 |
Int Read(char[] buf, int offset, int num) |
Делает попытку прочитать num символов в массив buf, начиная с элемента buf [offset], и возвращает количество успешно считанных символов |
4 |
Bool ReadBoolean() |
Считывает bool-значение |
5 |
Bool ReadByte() |
Считывает byte-значение |
6 |
Bool ReadSByte() |
Считывает sbyte-значение |
7 |
Byte[] ReadBytes(int num) |
Считывает num байтов и возвращает их в виде массива |
8 |
Char ReadChar() |
Считывает char- значение |
9 |
Char[] ReadChars(int num) |
Считывает num символов и возвращает их в виде массива |
10 |
Double ReadDouble() |
Считывает double- значение |
11 |
Float ReadSingle() |
Считывает float- значение |
12 |
shortReadInt16() |
Считывает short- значение |
13 |
Int ReadInt32() |
Считывает int- значение |
14 |
Long ReadInt64() |
Считывает long - значение |
15 |
ushortReadUint16() |
Считывает ushort- значение |
16 |
Uint ReadUint32 |
Считывает uint- значение |
17 |
Ulong ReadUint64() |
Считывает ulong- значение |
18 |
String ReadStrung() |
Считывает string – значение, представленное во внутреннем двоичном формате, который включает спецификатор длины. Этот метод следует использовать для считывания строки, которая была записана с помощью объекта класса BinaryWriter. |
_
-
Применение двоичного ввода-вывода
№ 11
// Запись и считывание двоичных данных
using System;
using System.IO;
class ReadWriteData{
public static void Main() {
BinaryWriter dataOut;
BinaryReader dataIn;
int i = 2147483647; //max = 2147483647
double d = 4.98765432100123456789E-324; // min = 5E-324
bool b = true;
try { dataOut = new
BinaryWriter (new FileStream("testdata",FileMode.Create));
}
catch(IOException exc) {
Console.WriteLine(exc.Message + "\n Не удается открыть файл.");
return;
}
try
{ Console.WriteLine("\n ");
Console.WriteLine(" Запись" + i);
dataOut.Write(i);
Console.WriteLine(" Запись" + d);
dataOut.Write(d);
Console.WriteLine(" Запись" + b);
dataOut.Write(b);
Console.WriteLine(" Запись" + 12.123456789 * 7.123456789);
dataOut.Write(12.123456789 * 7.123456789);
}
catch(IOException exc) {
Console.WriteLine(" " + exc.Message + "\n Ошибка при записи.");
}
dataOut.Close();
Console.WriteLine();
// Теперь попробуем прочитать эти данные.
try {
dataIn = new BinaryReader(
new FileStream("testdata", FileMode.Open));
}
catch(FileNotFoundException exc) {
Console.WriteLine(" " + exc.Message + "\n Не удается открыть файл.");
return;
}
try {
i = dataIn.ReadInt32();
Console.WriteLine(" Считывание " + i);
d = dataIn.ReadDouble();
Console.WriteLine(" Считывание " + d);
b = dataIn.ReadBoolean();
Console.WriteLine(" Считывание " + b);
d = dataIn.ReadDouble();
Console.WriteLine(" Считывание " + d);
}
catch(IOException exc) {
Console.WriteLine(" " + exc.Message + " Ошибка при считывании.");
}
Console.WriteLine("\n\n\n ");
dataIn.Close();
}
}
Рис 11 Результаты записи в файл двоичных данных разных типов
и дальнейшего считывания их на экран
2.6 Файлы с произвольным доступом
Расматриваются файлы со случайным доступом (до этого рассматривались файлы с последовательным доступом - байт за байтом, символ за символом)ю\. Для этого используется метод Seek() из класса FileStream, со следующим заголовком: Long Seek(long newPos, SeekOrigin origin)
где newPos – позиция, выраженная в байтах;
origin – файловый указатель относительно позиции (SeekOrigin).
Элемент origin принимает одно из значений, определенных перечислением SeekOrigin (см. таблицу).
№ |
Значение |
Описание |
1 |
SeekOrigin.Begin |
Поиск от начала файла |
2 |
SeekOrigin.Current |
Поиск от текущей позиции |
3 |
SeelOrigin.End |
Поиск от конца файла |
После обращения к Seek() следующая операция чтения или записи будет выполняться на новой позиции в файле. Генерируются следующие ИС:
IOException – при возникновении любой ошибки при поиске;
NotSupportedException – базовый поток не поддерживает функцию запроса.
№ 12
// Производный доступ к файлу
using System;
using System.IO;
class RandomAccess
{ public static void Main()
{ FileStream f;
char ch;
try
{ f = new FileStream(" random.dat", FileMode.Create);
}
catch (IOException exc)
{ Console.WriteLine(exc.Message);
return;
}
// Записываем в файл алфавит.
for (int i = 0; i < 26; i++)
{ try {
f.WriteByte((byte)('A' + i));
}
catch (IOException exc)
{ Console.WriteLine(exc.Message);
return;
}
}
try {
// Теперь считываем отдельные значения.
f.Seek(0, SeekOrigin.Begin); //Поиск первого байта
ch = (char)f.ReadByte();
Console.WriteLine("\n Первое значение равно " + ch);
f.Seek(1, SeekOrigin.Begin); //Поиск второго байта
ch = (char)f.ReadByte();
Console.WriteLine(" Второе значение равно " + ch);
f.Seek(4, SeekOrigin.Begin); //Поиск пятого байта
ch = (char)f.ReadByte();
Console.WriteLine(" Пятое значение равно " + ch);
Console.WriteLine();
// Теперь считываем значения все подряд.
Console.WriteLine("\n\n Выборка значений подряд: ");
for (int i = 0; i < 26; i += 1)
{ f.Seek(i, SeekOrigin.Begin); // Переход к i-му байту
ch = (char)f.ReadByte();
Console.Write(" " + ch );
}
// Теперь считываем значения через два.
Console.WriteLine("\n\n Выборка значений через два: ");
for (int i = 0; i < 26; i += 3)
{ f.Seek(i, SeekOrigin.Begin); // Переход к i-му байту
ch = (char)f.ReadByte();
Console.Write(" " + ch + " ");
}
// Теперь считываем значения через пять.
Console.WriteLine("\n\n Выборка значений через 5: ");
for (int i = 0; i < 26; i += 6)
{ f.Seek(i, SeekOrigin.Begin); // Переход к i-му байту
ch = (char)f.ReadByte();
Console.Write(" " + ch + " ");
}
}
catch (IOException exc)
{ Console.WriteLine(" ", exc.Message);
}
Console.WriteLine("\n\n\n ");
f.Close();
}
}
Рис 12 Демонстрация произвольного вывода байтов (символов алфавита)