Главная | Обратная связь
МегаЛекции

Как обнаружить конец файла?





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

Обнаружить конец файла при чтении данных позволяет функция потока:

 

bool eof ();

 

Эта функция не имеет параметров и возвращает значение true, когда достигается конец файла. Пример использования этой функции можно увидеть в одном из предыдущих примеров.

Другой способ определения конца файла основан на том, что функции чтения данных из файла (get (), read ()) при достижении конца файла возвращают нулевую ссылку на поток. Этот способ иллюстрируется в последнем примере.

Прямой доступ при работе с файлами

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

Поддержка этих методов основана на понятии указателя позиции в файле (или просто – указателя). В языке C++ поддерживается работа с двумя указателями. Один указатель (get-указатель) определяет место в файле, откуда должны быть прочитаны данные. Другой – put-указатель определяет место для записи данных. При выполнении операций чтения-записи соответствующие указатели автоматически перемещаются в файле на расстояние, равное объему прочитанных или записанных данных, тем самым подготавливая следующую операцию чтения или записи.

Замечание. Рассматриваемые далее методы ориентированы на использование в двоичном режиме работы с файлами. В текстовом режиме позиционирование указателей может оказаться не точным.

Перемещение указателей в потоках осуществляется с помощью соответствующих потоковых функций:

· ifstream &seekg ( off_type offset, seekdir way ); - перемещение get-указателя;

· ofstream &seekp ( off_type offset, seekdir way ); - перемещение put-указателя.



Перемещение соответствующего указателя осуществляется на offset байт (тип данных off_ type – целочисленный тип данных, может принимать отрицательные и положительные значения) относительно точки, задаваемой параметром way.

Тип данных seekdir параметра way имеет три возможных значения:

· ios :: beg – начало файла;

· ios :: cur – текущая позиция;

· ios :: end – конец файла.

Существуют перегруженные функции позиционирования указателей, обеспечивающие абсолютную адресацию указателя в заданную позицию файла:

· ifstream & seekg ( pos_ type pos ); - перемещение get-указателя в позицию pos;

· ofstream & seekp ( pos_ type pos ); - перемещение put-указателя в позицию pos.

Тип данных pos_ type является целочисленным беззнаковым типом. Позиция 0 соответствует началу файла.

Определить текущие позиции указателей можно с помощью следующих потоковых функций:

pos_ type tellg (); - возвращает текущую позицию get-указателя;

pos_ type tellp (); - возвращает текущую позицию put-указателя;

В качестве иллюстрации напишем функцию, возвращающую размер в байтах заданного файла:

 

unsigned FileSize ( char *FileName)

{

ifstream File ( FileName, ios::in | ios::binary );

if ( ! File ) // Проверили удалось ли открыть файл

{

            cout << "Файл не найден! \ n" ;

            return 0;

}

File.seekg (0, ios::end );

unsigned Size = File.tellg();

File.close ();

return Size;

}

Статус потоков ввода-вывода

Потоки ввода-вывода после выполнения каждой операции ввода-вывода находятся в определенном состоянии, характеризующимся, так называемым, статусом потока. Статус потока ввода-вывода представляет собой перечисление, имеющее следующие значения:

· ios :: goodbit – нормальное состояние потока – ошибки отсутствуют;

· ios :: eofbit – достигнут конец файла;

· ios :: failbit – исправимая ошибка;

· ios :: bedbit – неисправимая ошибка.

Значение статуса после завершения очередной операции ввода-вывода можно узнать с помощью функции rdstate (), которая возвращает значение одного из перечисленных выше значений:

 

fstream File (……..);

while (File.rdstate () = ios :: goodbit)

{

  // Выполняем очередную операцию с файлом

}

 

Еще один способ узнать значение статуса потока ввода-вывода состоит в использовании одной из следующих функций потока, возвращающих значение true, при установке соответствующего флага статуса:

· bool good ()

· bool eof () – эту функцию мы уже использовали раньше

· bool fail ()

· bool bed ()

 

Например:

 

fstream File (……..);

While ( File.good () )

{

  // Выполняем очередную операцию с файлом

}

 

Если после выполнения очередной операции ввода-вывода установлен статус потока отличающийся от ios :: goodbit, дальнейшее выполнение операций по работе с потоком может стать невозможным. Для попытки продолжения работы с потоком в этом случае следует воспользоваться потоковой функцией clear (). Эта функция очищает статус потока ввода-вывода и устанавливает флаг статуса ios :: goodbit.

Некоторые другие функции управления потоками ввода-вывода

Функция потока ввода peek () позволяет прочитать из потока очередной символ, не удаляя его из потока.

Функция putback ( char c) возвращает в поток ввода символ c.

При выводе данных на некоторое устройство эти данные сначала накапливаются в буфере вывода и, когда этот буфер заполняется, сбрасываются на устройство (например, запись на диск). Этот прием называется буферизацией данных. Он позволяет существенно увеличить быстродействие операций вывода данных. Однако в некоторых ситуациях требуется осуществлять запись данных на устройство, не дожидаясь заполнения буфера. Для этого можно использовать функцию потока вывода flush ().





Рекомендуемые страницы:

Воспользуйтесь поиском по сайту:
©2015- 2020 megalektsii.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.