Чтение онлайн

на главную - закладки

Жанры

Полное руководство. С# 4.0
Шрифт:

где offset обозначает новое положение указателя файла в байтах относительно за данного начала отсчета (origin). В качестве origin может быть указано одно из при веденных ниже значений, определяемых в перечислении SeekOrigin. Значение Описание SeekOrigin.Begin Поиск от начала файла SeekOrigin.Current Поиск от текущего положения SeekOrigin.End Поиск от конца файла

Следующая операция чтения или записи после вызова метода Seek будет выпол няться, начиная с нового положения в файле, возвращаемого этим методом. Если во время поиска в файле возникает ошибка, то генерируется исключение IOException. Если же запрос положения в файле не поддерживается базовым потоком, то генери руется исключение NotSupportedException. Кроме того, могут быть сгенерированы и другие исключения.

В приведенном ниже примере программы демонстрируется ввод-вывод

в файл с произвольным доступом. Сначала в файл записываются прописные буквы английско го алфавита, а затем его содержимое считывается обратно в произвольном порядке. // Продемонстрировать произвольный доступ к файлу. using System; using System.IO; class RandomAccessDemo { static void Main { FileStream f = null; char ch; try { f = new FileStream("random.dat", FileMode.Create); // Записать английский алфавит в файл. for (int i=0; i < 26; i++) f.WriteByte((byte)('A'+i)); // А теперь считать отдельные буквы английского алфавита. f.Seek(0, SeekOrigin.Begin); // найти первый байт ch = (char) f.ReadByte; Console.WriteLine("Первая буква: " + 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("Буквы алфавита через одну: "); for(int i=0; i < 26; i += 2) { f.Seek(i, SeekOrigin.Begin); // найти i-й символ ch = (char) f.ReadByte; Console.Write(ch + " "); } } catch(IOException exc) { Console.WriteLine("Ошибка ввода-вывода\n" + exc.Message); } finally { if(f != null) f.Close; } Console.WriteLine; } }

При выполнении этой программы получается следующий результат. Первая буква: А Вторая буква: В Пятая буква: Е Буквы алфавита через одну: А C E G I K M O Q S U W Y

Несмотря на то что метод Seek имеет немало преимуществ при использовании с файлами, существует и другой способ установки текущего положения в файле с по мощью свойства Position. Как следует из табл. 14.2, свойство Position доступно как для чтения, так и для записи. Поэтому с его помощью можно получить или же установить текущее положение в файле. В качестве примера ниже приведен фрагмент кода из предыдущей программы записи и чтения из файла с произвольным досту пом random.dat, измененный с целью продемонстрировать применение свойства Position. Console.WriteLine("Буквы алфавита через одну: "); for(int i=0; i < 26; i += 2) { f.Position = i; // найти i-й символ посредством свойства Position ch = (char) f.ReadByte; Console.Write(ch + " "); } Применение класса MemoryStream

Иногда оказывается полезно читать вводимые данные из массива или записывать выводимые данные в массив, а не вводить их непосредственно из устройства или вы водить прямо на него. Для этой цели служит класс MemoryStream. Он представляет собой реализацию класса Stream, в которой массив байтов используется для ввода и вывода. В классе MemoryStream определено несколько конструкторов. Ниже пред ставлен один из них: MemoryStream(byte[] buffer)

где buffer обозначает массив байтов, используемый в качестве источника или адре сата в запросах ввода-вывода. Используя этот конструктор, следует иметь в виду, что массив buffer должен быть достаточно большим для хранения направляемых в него данных.

В качестве примера ниже приведена программа, демонстрирующая применение класса MemoryStream в операциях ввода-вывода. // Продемонстрировать применение класса MemoryStream. using System; using System.IO; class MemStrDemo { static void Main { byte[] storage = new byte[255]; // Создать запоминающий поток. MemoryStream memstrm = new MemoryStream(storage); // Заключить объект memstrm в оболочки классов // чтения и записи данных в потоки. StreamWriter memwtr = new StreamWriter(memstrm); StreamReader memrdr = new StreamReader(memstrm); try { // Записать данные в память, используя объект memwtr. for(int i=0; i < 10; i++) memwtr.WriteLine("byte [" + i + "]: " + i); // Поставить в конце точку. memwtr.WriteLine("."); memwtr.Flush; Console.WriteLine("Чтение прямо из массива storage: "); // Отобразить содержимое массива storage непосредственно, foreach(char ch in storage) { if (ch == '.') break; Console.Write(ch); } Console.WriteLine("\nЧтение из потока с помощью объекта memrdr: "); // Читать из объекта memstrm средствами ввода данных из потока. memstrm.Seek(0, SeekOrigin.Begin); // установить указатель файла // в исходное положение string str = memrdr.ReadLine; while(str != null) { str = memrdr .ReadLine; if (str[0] == '.') break; Console.WriteLine(str); } } catch(IOException exc) { Console.WriteLine("Ошибка

ввода-вывода\n" + exc.Message); } finally { // Освободить ресурсы считывающего и записывающего потоков. memwtr.Close; memrdr.Close; } } }

Вот к какому результату приводит выполнение этой программы. Чтение прямо из массива storage: byte [0]: 0 byte [1]: 1 byte [2]: 2 byte [3]: 3 byte [4]: 4 byte [5]: 5 byte [6]: 6 byte [7]: 7 byte [8]: 8 byte [9]: 9 Чтение из потока с помощью объекта memrdr: byte [1]: 1 byte [2]: 2 byte [3]: 3 byte [4]: 4 byte [5]: 5 byte [6]: 6 byte [7]: 7 byte [8]: 8 byte [9]: 9

В этой программе сначала создается массив байтов, называемый storage. Затем этот массив используется в качестве основной памяти для объекта memstrm класса MemoryStream. Из объекта memstrm, в свою очередь, создаются объекты memrdr клас са StreamReader и memwtr класса StreamWriter. С помощью объекта memwtr выво димые данные записываются в запоминающий поток. Обратите внимание на то, что после записи выводимых данных для объекта memwtr вызывается метод Flush. Это необходимо для того, чтобы содержимое буфера этого объекта записывалось непо средственно в базовый массив. Далее содержимое базового массива байтов отобража ется вручную в цикле foreach. После этого указатель файла устанавливается с по мощью метода Seek в начало запоминающего потока, из которого затем вводятся данные с помощью объекта потока memrdr.

Запоминающие потоки очень полезны для программирования. С их помощью можно, например, организовать сложный вывод с предварительным накоплением данных в массиве до тех пор, пока они не понадобятся. Этот прием особенно поле зен для программирования в такой среде с графическим пользовательским интер фейсом, как Windows. Кроме того, стандартный поток может быть переадресован из массива. Это может пригодиться, например, для подачи тестовой информации в программу. Применение классов StringReader и StringWriter

Для выполнения операций ввода-вывода с запоминанием в некоторых приложе ниях в качестве базовой памяти иногда лучше использовать массив типа string, чем массив типа byte. Именно для таких случаев и предусмотрены классы StringReader и StringWriter. В частности, класс StringReader наследует от класса TextReader, а класс StringWriter — от класса TextWriter. Следовательно, они представля ют собой потоки, имеющие доступ к методам, определенным в этих двух базовых классах, что позволяет, например, вызывать метод ReadLine для объекта класса StringReader, а метод WriteLine — для объекта класса StringWriter.

Ниже приведен конструктор класса StringReader: StringReader(string s)

где s обозначает символьную строку, из которой производится чтение.

В классе StringWriter определено несколько конструкторов. Ниже представлен один из наиболее часто используемых. StringWriter

Этот конструктор создает записывающий поток, который помещает выводимые данные в строку. Для получения содержимого этой строки достаточно вызвать метод ToString.

Ниже приведен пример, демонстрирующий применение классов StringReader и StringWriter. // // Продемонстрировать применение классов StringReader и StringWriter. using System; using System.IO; class StrRdrWtrDemo { static void Main { StringWriter strwtr = null; StringReader strrdr = null; try { // Создать объект класса StringWriter. strwtr = new StringWriter; // Вывести данные в записывающий поток типа StringWriter. for (int i=0; i < 10; i++) strwtr.WriteLine("Значение i равно: " + i); // Создать объект класса StringReader. strrdr = new StringReader(strwtr.ToString); //А теперь ввести данные из считывающего потока типа StringReader. string str = strrdr.ReadLine; while(str != null) { str = strrdr.ReadLine; Console.WriteLine(str); } } catch(IOException exc) { Console.WriteLine("Ошибка ввода-вывода\n" + exc.Message); } finally { // Освободить ресурсы считывающего и записывающего потоков. if(strrdr != null) strrdr.Close; if(strwtr != null) strwtr.Close; } } }

Вот к каком результату приводит выполнение этого кода. Значение i равно: 1 Значение i равно: 2 Значение i равно: 3 Значение i равно: 4 Значение i равно: 5 Значение i равно: 6 Значение i равно: 7 Значение i равно: 8 Значение i равно: 9

В данном примере сначала создается объект strwtr класса StringWriter, в кото рый выводятся данные с помощью метода WriteLine. Затем создается объект класса StringReader с использованием символьной строки, содержащейся в объекте strwtr. Эта строка получается в результате вызова метода ToString для объекта strwtr. И наконец, содержимое данной строки считывается с помощью метода ReadLine. Класс File

Поделиться:
Популярные книги

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Пипец Котенку! 4

Майерс Александр
4. РОС: Пипец Котенку!
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Пипец Котенку! 4

Маленькая хозяйка большого герцогства

Вера Виктория
2. Герцогиня
Любовные романы:
любовно-фантастические романы
7.80
рейтинг книги
Маленькая хозяйка большого герцогства

Новый Рал 8

Северный Лис
8. Рал!
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Новый Рал 8

Законы Рода. Том 6

Flow Ascold
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 6

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Делегат

Астахов Евгений Евгеньевич
6. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Делегат

Целительница моей души

Чекменёва Оксана
Любовные романы:
любовно-фантастические романы
7.29
рейтинг книги
Целительница моей души

На границе империй. Том 4

INDIGO
4. Фортуна дама переменчивая
Фантастика:
космическая фантастика
6.00
рейтинг книги
На границе империй. Том 4

Мастер Разума II

Кронос Александр
2. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.75
рейтинг книги
Мастер Разума II

Здравствуй, 1985-й

Иванов Дмитрий
2. Девяностые
Фантастика:
альтернативная история
5.25
рейтинг книги
Здравствуй, 1985-й

Мужчина моей судьбы

Ардова Алиса
2. Мужчина не моей мечты
Любовные романы:
любовно-фантастические романы
8.03
рейтинг книги
Мужчина моей судьбы

Лишняя дочь

Nata Zzika
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Лишняя дочь

Релокант. Вестник

Ascold Flow
2. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант. Вестник