Страница 214 из 502
<b> // Проверить, совпадает ли он с запрашиваемым предметом.</b>
<b> // Если совпадает, то отобразить сведения о нем.</b>
<b> if(item.Equals(what, StringComparison.OrdinalIgnoreCase)) {</b>
<b> Console.WriteLine(item + ": " + onhand + " штук в наличии. " +</b>
<b> "Цена: {0:С} за штуку", cost);</b>
<b> Console.WriteLine("Общая стоимость по наименованию <{0}>: {1:С}.",</b>
<b> item, cost * onhand);</b>
<b> break;</b>
<b> }</b>
<b> }</b>
<b> }</b>
<b> catch(EndOfStreamException) {</b>
<b> Console.WriteLine("Предмет не найден.");</b>
<b> }</b>
<b> catch(IOException exc) {</b>
<b> Console.WriteLine("Ошибка чтения из файла товарных запасов");</b>
<b> Console.WriteLine("Причина: " + exc.Message);</b>
<b> } finally {</b>
<b> dataIn.Close();</b>
<b> }</b>
<b> }</b>
<b>}</b>
Выполнение этой программы может привести, например, к следующему результату.
<b>Введите наименование для поиска: Отвертки</b>
<b>Отвертки: 18 штук в наличии. Цена: $1.50 за штуку.</b>
<b>Общая стоимость по наименованию <Отвертки>: $27.00.</b>
Обратите внимание на то, что сведения о товарных запасах сохраняются в этой программе в двоичном формате, а не в удобной для чтения текстовой форме. Благодаря этому обработка числовых данных может выполняться без предварительного их преобразования из текстовой формы.
Обратите также внимание на то, как в этой программе обнаруживается конец файла. Методы двоичного ввода генерируют исключение EndOfStreamException по достижении конца потока, и поэтому файл читается до тех пор, пока не будет найден искомый предмет или сгенерировано данное исключение. Таким образом, для обнаружения конца файла никакого специального механизма не требуется.
Файлы с произвольным доступом
В предыдущих примерах использовались последовательные файлы, т.е. файлы со строго линейным доступом, байт за байтом. Но доступ к содержимому файла может быть и произвольным. Для этого служит, в частности, метод Seek(), определенный в классе FileStream. Этот метод позволяет установить указатель положения в файле, или так называемый указатель файла, на любое место в файле. Ниже приведена общая форма метода Seek():
<b>long Seek(long offset, SeekOrigin origin)</b>
где offset обозначает новое положение указателя файла в байтах относительно заданного начала отсчета (origin). В качестве origin может быть указано одно из приведенных ниже значений, определяемых в перечислении SeekOrigin.
Значение - Описание
SeekOrigin.Begin - Поиск от начала файла
SeekOrigin.Current - Поиск от текущего положения
SeekOrigin.End - Поиск от конца файла
Следующая операция чтения или записи после вызова метода Seek() будет выполняться, начиная с нового положения в файле, возвращаемого этим методом. Если во время поиска в файле возникает ошибка, то генерируется исключение IOException. Если же запрос положения в файле не поддерживается базовым потоком, то генерируется исключение NotSupportedException. Кроме того, могут быть сгенерированы и другие исключения.
В приведенном ниже примере программы демонстрируется ввод-вывод в файл с произвольным доступом. Сначала в файл записываются прописные буквы английского алфавита, а затем его содержимое считывается обратно в произвольном порядке.
<b>// Продемонстрировать произвольный доступ к файлу.</b>
<b>using System; </b>
<b>using System.IO;</b>
<b>class RandomAccessDemo {</b>
<b> static void Main() {</b>
<b> FileStream f = null;</b>
<b> char ch;</b>
<b> try {</b>
<b> f = new FileStream("random.dat", FileMode.Create);</b>
<b> // Записать английский алфавит в файл,</b>
<b> for (int i=0; i < 26; i++) f.WriteByte((byte)('A'+i));</b>
<b> //А теперь считать отдельные буквы английского алфавита.</b>
<b> f.Seek(0, SeekOrigin.Begin); // найти первый байт </b>
<b> ch = (char) f.ReadByte() ;</b>
<b> Console.WriteLine("Первая буква: " + ch) ;</b>
<b> f.Seek(l, SeekOrigin.Begin); // найти второй байт </b>
<b> ch = (char) f.ReadByte() ;</b>
<b> Console.WriteLine("Вторая буква: " + ch);</b>
<b> f.Seek(4, SeekOrigin.Begin); // найти пятый байт </b>