Добавить в цитаты Настройки чтения

Страница 214 из 502

<b>        // Проверить, совпадает ли он с запрашиваемым предметом.</b>

<b>        // Если совпадает, то отобразить сведения о нем.</b>

<b>        if(item.Equals(what, StringComparison.OrdinalIgnoreCase)) {</b>

<b>          Console.WriteLine(item + &quot;: &quot; + onhand + &quot; штук в наличии. &quot; +</b>

<b>             &quot;Цена: {0:С} за штуку&quot;, cost);</b>

<b>          Console.WriteLine(&quot;Общая стоимость по наименованию &lt;{0}&gt;: {1:С}.&quot;,</b>

<b>             item, cost * onhand);</b>

<b>          break;</b>

<b>        }</b>

<b>      }</b>

<b>    }</b>

<b>    catch(EndOfStreamException) {</b>

<b>      Console.WriteLine(&quot;Предмет не найден.&quot;);</b>

<b>    }</b>

<b>    catch(IOException exc) {</b>

<b>      Console.WriteLine(&quot;Ошибка чтения из файла товарных запасов&quot;);</b>

<b>      Console.WriteLine(&quot;Причина: &quot; + exc.Message);</b>

<b>    } finally {</b>

<b>      dataIn.Close();</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

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

<b>Введите наименование для поиска: Отвертки</b>

<b>Отвертки: 18 штук в наличии. Цена: $1.50 за штуку.</b>

<b>Общая стоимость по наименованию &lt;Отвертки&gt;: $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(&quot;random.dat&quot;, FileMode.Create);</b>

<b>      // Записать английский алфавит в файл,</b>

<b>      for (int i=0; i &lt; 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(&quot;Первая буква: &quot; + ch) ;</b>

<b>      f.Seek(l, SeekOrigin.Begin); // найти второй байт </b>

<b>      ch = (char) f.ReadByte() ;</b>

<b>      Console.WriteLine(&quot;Вторая буква: &quot; + ch);</b>

<b>      f.Seek(4, SeekOrigin.Begin); // найти пятый байт </b>