Вход/Регистрация
Полное руководство. С# 4.0
вернуться

Шилдт Герберт

Шрифт:

Выполнение этой программы может привести, например, к следующему результату. Введите наименование для поиска: Отвертки Отвертки: 18 штук в наличии. Цена: $1.50 за штуку. Общая стоимость по наименованию <Отвертки>: $27.00.

Обратите внимание на то, что сведения о товарных запасах сохраняются в этой про грамме в двоичном формате, а не в удобной для чтения текстовой форме. Благодаря этому обработка числовых данных может выполняться без предварительного их пре образования из текстовой формы.

Обратите также внимание на то, как в этой программе обнаруживается конец фай ла. Методы двоичного ввода генерируют исключение EndOfStreamException по до стижении конца потока, и поэтому файл читается до тех пор, пока не будет найден искомый предмет или сгенерировано данное исключение. Таким образом, для обна ружения конца файла никакого специального механизма не требуется. Файлы с произвольным доступом

В предыдущих примерах использовались последовательные файлы, т.е. файлы со строго линейным доступом, байт за байтом. Но доступ к содержимому файла может быть и произвольным. Для этого служит, в частности, метод Seek, определенный в классе FileStream. Этот метод позволяет установить указатель положения в файле, или так называемый указатель файла, на любое место в файле. Ниже приведена общая форма метода Seek: long Seek(long offset, SeekOrigin origin)

где 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.

  • Читать дальше
  • 1
  • ...
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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