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


Файлы с последовательным доступом:

 


рис.3

Адр(запись i) = ???

 

Файлы с прямым доступом:

Способ 1.

 

 

рис.4

 

Length(Запись 1) = Length(Запись 2) = Length(Запись N)=const

 

Адр(Запись i) = Length(Запись) * (i-1) байт

 

Способ 2. Файл адресов записей: Адр(запись i) = Адр[i-1]

 

 

 


рис.5

 

Для доступа к требуемой записи необхо­димо использовать метод Seek(), определенный в классе FileStream. Этот метод по­зволяет установить указатель позиции (файловый указатель) в любое место файла.

Формат:

 

long Seek (long newPos, SeekOrigin origin)

 

newPos - новая позиция файлового указателя, выраженная в байтах, относительно позиции, заданной элементом origin. Перемещаться можно как вперед (+), так и назад (-).

Элемент origin мо­жет принимать одно из значений, определенных перечислением SeekOrigin:

 

Значение Описание
SeekOrigin.Begin Поиск от начала файла
SeekOrigin.Current Поиск от текущей позиции
SeekOrigin.End Поиск от конца файла

 

 

После обращению к методу Seek() следующая операция чтения или записи дан­ных будет выполняться на новой позиции в файле.

 

Исключение Описание
IOException Ошибка ввода-вывода
NotSuppotedException Базо­вый поток не поддерживает эту функцию

 

f = new FileStream ("random.dat", FileMode.Create);

 

f.Seek(0, SeekOrigin.Begin); // Переход в начало файла.

f.Seek(4, SeekOrigin.Begin); // Поиск пятого байта (№ б. = 4).

 

f.Seek(-10, SeekOrigin.End); // Поиск одиннадцатого байта от конца.

// Демонстрация произвольного доступа к файлу.

// Записать в файл алфавит прописными буквами,

// а затем выборочно считать его.

using System;

using System.IO;

class RandomAccessDemo

{

public static void Main()

{

FileStream f;

char ch;

try

{

f = new FileStream ("random.dat", FileMode.Create);

}

catch (IOException exc)

{

Console.WriteLine (exc.Message);

return;

}

// Записываем в файл алфавит.

for ( int i = 0; i < 26; i++)

{

try

{

f.WriteByte ((byte)('A' + i));

}

catch (IOException exc)

{

Console.WriteLine (exc.Message);

return;

}

}

try

{

// Теперь считываем отдельные значения.

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 (exc.Message);

}

Console.WriteLine();

f.Close();

}

}

 

При выполнении этой программы получены такие результаты:

Первое значение равно А

Второе значение равно В

Пятое значение равно Е

Выборка значений через одно: ACEGIKMOQSUWY

 

Проблемы.

Строки имеют переменную длину (по фактическому содержимому). Решением проблемы м.б.: 1) добаление к строкам пробелов до одинаковой длины методом PadRicht(); 2) преобразование строки в массив символов методом ToCharArray().

 

В кодировке, используемой по умолчанию (UTF8), русские буквы кодируются двумя байтами, а английские – одним. Решение проблемы: указывать кодировку явно, например, System.Text.Encoding.Unicode.

 



Дата добавления: 2019-02-08; просмотров: 548;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.011 сек.