Книга: C# 4.0: полное руководство

Файлы с произвольным доступом

Файлы с произвольным доступом

В предыдущих примерах использовались последовательные файлы, т.е. файлы со строго линейным доступом, байт за байтом. Но доступ к содержимому файла может быть и произвольным. Для этого служит, в частности, метод 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(l, 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("Ошибка ввода-вывода" + exc.Message);
    } finally {
      if(f != null) f.Close();
    }
    Console.WriteLine() ;
  }
}

При выполнении этой программы получается следующий результат.

Первая буква: А
Вторая буква: В
Пятая буква: Е
Буквы алфавита, через одну:
А С Е 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 + " ");
}

Оглавление книги


Генерация: 1.113. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз