68972

Файли. Робота з файлами. Файловий ввід-вивід

Лекция

Информатика, кибернетика и программирование

Не дивлячись на те що система введення-виведення мови C++ в цілому є єдиним механізмом, система файлового введення-виведення має свої особливості. Частково це пояснюється тим, що на практиці найчастіше використовуються файли на жорсткому диску, можливості яких значно відрізняються від всіх інших пристроїв.

Украинкский

2014-09-28

58 KB

5 чел.

Лекція № 17

Тема: Файли. Робота з файлами.

План

  1.  Файловий ввід-вивід
  2.  Відкриття і закриття потоку
  3.  Читання і запис текстових файлів
  4.  Безформатне і бінарне введення-виведення

Файловий ввід-вивід

Не дивлячись на те що система введення-виведення мови C++ в цілому є  єдиним механізмом, система файлового введення-виведення має свої особливості. Частково це пояснюється тим, що на практиці найчастіше використовуються файли на жорсткому диску, можливості яких значно відрізняються від всіх інших пристроїв. Проте слід мати на увазі, що файлове уведення-виведення є лише частиною загальної системи введення-виведення, і велика частина матеріалу, викладеного в розділі, відноситься до потоків, які можуть бути пов'язані з іншими пристроями.

Для реалізації файлового введення-виведення в програму слід включити заголовок <fstream>. У нім визначені деякі класи, зокрема, ifstream, ofstream і f stream. Ці класи є похідними від класів istream, ostream і ios-tream відповідно. Слід пам'ятати, що класи istream, ostream і iostream, у свою чергу, є похідними від класу ios, розглянутого в попередньому розділі. Файлова система використовує також клас filebuf, що надає низкоуровневые засоби управління файловим потоком. Зазвичай клас filebuf непосредственно не застосовується, проте він є складовою частиною інших класів.

 

Відкриття і закриття файлу

У мові C++ відкриття файлу означає його пов'язання з потоком. Отже, спочатку необхідно отримати потік. Існують три види потоків: введення, виведення і введення-виведення. Для того, щоб створити потік введення, необхідно оголосити потік, що є об'єктом класу ifstream Для генерації потоку виведення необхідно оголосити потік, що є об'єктом класу ofstream. Потоки, здійснююче введення і виведення, оголошуються як об'єкти класу fstream Наприклад, в наступному фрагменті створюється потік введення, потік виведення і потік введення-виведення.

ifstream in;  // Введення

ofstream out; // Виведення

fstream io;   // Введення і виведення

Створений потік можна пов'язати з файлом за допомогою функції ореn(). Ця функція є членом кожного з трьох потокових класів. Її прототипи в кожному класі показані нижче.

ifstream::open(const char *filename, ios::openmode

mode = ios::in);

ifstream: : open (const char  * filename,   

ios : : openmode mode = ios::out | ios::trunc);

ifstream::open(const  char  * filename,   

ios::openmode mode = ios::in   |   ios::out);

Тут параметр filename задає ім'я файлу. Він може містити шлях до цього файлу. Значення параметра mode визначає спосіб відкриття файлу. Цей параметр може приймати наступні значення, описані у функції openmode.

ios::арр ios::ate ios::binary ios::in ios::out ios::trunc

Дані значення можна комбінувати за допомогою логічної операції "АБО". Якщо задається значення ios:: арр, всі результати дописуються в кінець файлу, що риється для виведення. Якщо вказано значення ios: :ate, при відкритті виконується позов кінця файлу. Не дивлячись на це, запис проводиться в будь-яке місце файлу. Якщо задається значення ios:: in, файл відкривається для введення, а якщо ios:: out —  виведення.

Значення ios::binary дозволяє відкрити файл в бінарному режимі. По замовчуванню всі файли відкриваються в текстовому режимі. В цьому випадку проводиться перетворення деяких символів, наприклад, ескейп-послідовність "повернення каретки" і "прогін паперу" перетвориться в символ переходу на новий рядок. Проте, файл відкритий в бінарному режимі, перетворення символів не проводиться. Слід пам'ятати, що будь-який файл можна відкрити як в текстовому, так і в бінарному режимі. Єдина відмінність між ними полягає в тому, проводиться перетворення символів чи ні.

Значення ios::trunc сигналізує, що попередній вміст існуючого файлу з тим же ім'ям буде знищений, а довжина файлу зменшена до нуля. При відкритті потоку виведення за допомогою класу ofstream вміст будь-якого існуючого файлу з вказаним ім'ям стирається. В наступному фрагменті відкривається текстовий файл для виведення.

 

ofstream out; out.open( "test", ios::out);

 

Проте функція open() рідко застосовується для відкриття файлів, оскільки для кожного типу потоку параметр mode має значення, задані за умовчанням. Прототипи функції open демонструють, що значення параметра mode, задане по замовчуванню, в класі ifstream рівне ios::in, в класі ofstream – ios::out | ios: :trunc, а в класі fstream — ios: :in | ios: :out. По цій причині попередній виклик функції open зазвичай записують так:

out.open(" test"); // Текстовий файл для виведення

Якщо потік застосовується в логічних виразах, у разі відмови функції open() йому привласнюється значення false. Таким чином, перед використанням файлу слід переконатися, що він успішно відкритий. Для цього можна скористатися наступними операторами.

if(!mystream)   {

cout «   "Неможливо відкрити  файл.\n";

// Обробка помилки

}

Однак частіше за все функцію ореn() не застосовують, оскільки класи ifstream, ofstream і fstream містять конструктори, що автоматично відкривають файл. Параметри цих конструкторів приймають ті ж значення за умовчанням, що і функція ореn(). З цієї причини файли зазвичай відкривають таким чином.

ifstream mystream( "myfile");   //  Відкриття файлу для  введення

Якщо з якої-небудь причини файл відкрити не вдалося, пов'язаному з ним потоку присвоюється значення false. Отже, якщо якийсь конструктор викликає функцію open(), слід переконатися, що файл дійсно відкритий, перевіривши значення потоку.

Щоб перевірити, чи відкритий файл, можна викликати функцію is_open(), яка є членом класу fstream, ifstream і ofstream. Вона має наступний прототип.

bool is_open();

Якщо потік пов'язаний з відкритим файлом, ця функція повертає значення true, інакше вона повертає значення false. Наприклад, наступний фрагмент перевіряє, чи відкритий файл, пов'язаний з потоком mystream.

if(!mystream.is_open())  {

cout «   "Файл не  відкритий.\n";

//   ...

}

Щоб закрити файл, слід викликати функцію close(). Наприклад, щоб закрити файл, пов'язаний з потоком mystream, можна застосувати наступний оператор

mystream.close() ;

Функція close () не має параметрів і не повертає ніяких значень.

Читання і запис текстових файлів

Читання і запис текстових файлів здійснюються дуже легко. Для цього достатньо застосувати операторів "<<" і ">>", як це зазвичай робиться для консольного введення-виведення, тільки замість потоків cin і cout необхідно підставити потік, що зв’язаний з файлом. Наприклад, наступна програма створює короткий файл, який містить назву предмету і його вартість.

#include <iostream>

#include <fstream>

using namespace std;

int main() {

ofstream out("INVNTRY"); // Текстовий файл для виведення.

if(!out){

cout « "Неможливо відкрити файл INVENTORY.\n";

return 1;

}

out << "Радіоприймачі " « 39.95 « endl;

out « "Тостери " « 19.95 « endl;

out « "Міксери " « 24.80 « endl;

out.close();

return 0;

}

Програма, приведена нижче, прочитує файл, створений попередньою програмою, і виводить його вміст на екран.

#include <iostream>

#include <fstream>

using namespace std;

int main () {

ifstream in("INVNTRY");   //  Введення

if(!in)  {

cout <<   "Неможливо відкрити  файл INVENTORY. \n" ;

return  1;

}

char item[20];

float cost;

in »  item »    cost;

cout «  item «   "   "  «  cost «   "\n"

in » item >> cost;

cout «  item «   "   "   «  cost «   "\n"

in >> item » cost;

cout «  item «   "   "   « cost «   "\n"

in.close() ;

return 0;

}

 

Читання і запис файлів за допомогою операторів "«" і "»" нагадує використання функцій fprintf() і fscanf() з мови С. Формат записів у файлі нічим не відрізняється від формату виведення на екран.

Прочитуючи файли за допомогою оператора ">>", майте на увазі, що деякі символи при введенні трансформуються. Наприклад, роздільники ігноруються. Щоб відмінити перетворення символів при читанні, файл слід відкрити в бинарному режимі і застосувати функції, описані в наступному розділі.

Якщо при введенні досягається кінець файлу, потоку, пов'язаному з файлом, присвоюється значення false. (Ця ситуація ілюструється в наступному розділі.)

 

Безформатне і бінарне уведення-виведення

Отже, читання і запис форматованих текстових файлів не викликає ніяких труднощів, хоча це не найефективніший спосіб роботи з файлами. Окрім цього іноді виникає необхідність зберігати безформатні дані, а не текст. Розглянемо функції, призначені для роботи з такими даними.

Виконуючи з файлом бінарні операції, слід переконатися, що він відкритий в режимі ios::binary. Безформатні дані можуть зберігатися і в текстовому файлі, але в цьому випадку при читанні деякі символи будуть перетворені. Бінарні файлу застосовуються саме для того, щоб цього уникнути.

Порівняння символів і байтів

При вивченні безформатного введення-виведення необхідно враховувати наступне. Багато років уведення-виведення в мовах С і C++ був байтовим (byte oriented). Це відбувалося тому, що символ (char) є еквівалентом байта, і потоки виведення були символьними. Проте з появою розширених символів (wchar_t і пов'язаних з ними потоків систему введення-виведення мови C++ не можна назвати байтовою. Тепер її слід називати символьною (character oriented). Зрозуміло, потоки звичайних символів (char) залишаються байтовими, особливо при обробці нетекстових даних. Проте еквівалентність понять "символ" і "байт" більше не гарантуєте

Ми використовуємо тільки символьні (тобто байтові) потоки, оскільки вони найширше поширені. Вони забезпечують простішу обробку безформатних файлів, оскільки символьні потоки збергіають однозначну відповідність між символами і байтами.

Функції put() і get()

Один із способів читання і запису безформатних файлів заснований на використанні функцій put () і get (). Ці функції оперують символами. Точніше кажучи, функція get () прочитує символ, а функція put () — записує його. Зрозуміло, якщо файл відкритий в бінарному режимі, то при прочитуванні символу (а не розширення символу), ці функції прочитують і записують байти.

Функція get () має декілька форм, проте найчастіше використовується її наступна версія.

istream &get(char &ch)

ostream &put(char ch)

Функція get () прочитує окремий символ з потоку і записує його в змінну ch. Крім того, функція get () повертає посилання на потік. Функція put() записує змінну ch в потік і повертає посилання на потік

Наступна програма відображає на екрані вміст будь-якого файлу (як текстового, так і бінарного). Для зчитування даних вона використовує функцію get ().

#include <iostream>

#include <fstream>

using namespace  std;

int main(int argc,   char  *argv[])

{

char  ch;

if(argc!=2){

cout << "виклик: PR <ім'я файла>\n";

return 1;

}

ifstream in(argv[l], ios::in | ios::binary);

if(!in){

cout « "Неможливо відкрити файл.";

return 1;

}

while(in)  {   //  Якщо досягнутий кінець файлу

//  значення  об'єкту  in рівне  false.

in.get(ch);

if(in)  cout  «   ch;

}

return 0;

}

Як указувалося в попередньому розділі, після досягнення кінця файлу потік, связанный з цим файлом, приймає значення false. Отже, рано чи пізно об'єкт in прийме значення false, і виконання циклу while припиниться.

Приведений вище цикл можна записати коротше.

while(in.get(ch)) cout «  ch;

Цей фрагмент є правильним, оскільки функція get () повертає ссылку на потік in, який прийме значення false при виявленні кінця файлу.

Функції read() і write()

Блоки бінарних даних можна прочитувати за допомогою функцій read() i  write(). Їх прототипи виглядають таким чином.

istream &read(char  *buf,   streamsize num);

istream &write(const char  *buf,   streamsize num);

Функція read прочитує num символів з потоку і записує їх в буфер, на який посилається покажчик buf. Функція write записує num символів в потік прочитуючи їх з буфера, на який посилається покажчик buf. Тип streamsize визначений в бібліотеці як різновид типу int. Він дозволяє зберігати максимальну кількість символів, які можуть перетворюватися при виконанні операцій введення-виведення.


 

А также другие работы, которые могут Вас заинтересовать

41486. Класс рыбы 187.5 KB
  Работа учителя по формированию природоохранных знаний при изучении рыб птиц млекопитающих. В курсе биологии в частности зоологии понятие об использовании биологических ресурсов раскрывается через понятие промысел промысловые птицы пушной промысел промысел морского зверя география и техника рыбного промысла и т. Используя такого рода факты при изучении классов рыб птиц и млекопитающих у школьников следует формировать понимание того что в условиях нашей формы хозяйства происходит постепенный процесс перехода от промысла...
41487. Методика формирования природоохранных знаний в процессе изучения зоологии 122.5 KB
  Деятельность учителя по углублению ряда ключевых понятий При изучении зоологии продолжается формированию представлений и начальных понятий о целостности природы которая отражается во взаимосвязанности природных процессов_ Это прежде всего предполагает расширение роли экологического материала формирование понятий о среде обитания и ее факторах приспособленности видов к среде обитания природных сообществах биоценозах. В курсе зоологии много возможностей конкретизировать представление о природных сообществах такими по нятиями...
41488. Цель и задачи преподавания охраны природы. Понятие охраны природы в щколном курсе биологии 124 KB
  Цель и задачи преподавания охраны природы. Понятие охраны природы в щколном курсе биологии. План Понятие Охрана природы и его педагогические аспекты. Глобальный характер воздействия человека на природу Цели охраны природы и цели преподавания этой дисциплины.
41489. Краткая историческая справка. Работа с учениками по охране природы, как одна из форм экологического вопсипания и образования 164 KB
  Работа с учениками по охране природы как одна из форм экологического вопсипания и образования . Книга для чтения по охране природы для учащихся 910 классов средней школы. Краткая историческая справка эволюция взглядов на охрану природы и ее преподавание. Методика преподавания охраны природы тесносвязана с эволюцией взгядов на эту проблему.
41490. ОСОБЕННОСТИ ФОРМИРОВАНИЯ ПРИРОДООХРАННЫХ ЗНАНИЙ В ПРОЦЕССЕ ИЗУЧЕНИЯ БОТАНИКИ 337.5 KB
  Курс ботаники располагает определенными возможностями тдля развития природоохранительных знаний на основе опорных понятии_о растительном организме особенностях его жизни о многообразии видов растений и их видовых сообществах. На уроках ботаники школьники изучают значение растений в жизни человека разнообразие влияний человеческой деятедьности на отдельные виды и целые растительные сообщества. Это способствует пониманию необходимости бережного отношения каждого человека к многообразию окружающих его растений охраны и рационального...
41491. Методика формирования природоохранных знаний в процессе изучения курса «Человек и его здоровье» 151 KB
  Трудовая деятельность человека и ее оптимизация. В курсе анатомии физиологии и гигиены человека VIII класса важно предусмотреть развитие основных понятий по охане природы закладываемых в предшествующих классах. Здесь полнее чем в других биологических предметах можно раскрыть гигиени ноский аспект взаимодействия природы и человека. Однако для понимания жизнедеятельности человека как биосоциального существа анализа только фнзикохимических условий жизни далеко не достаточно.
41492. Системы управления движением поездов 205.5 KB
  ДЦ способствует повышению безопасности движения позволяет обеспечить максимальное использование пропускной способности участков дает возможность четко организовать движение поездов по графику. Создаются системы слежения за движением поездов с контролем и отображением их номеров. При этом решаются и другие задачи: регистрация графика исполненного движения автоматическая установка поездных маршрутов оповещение пассажиров о подходе поездов контроль выполнения графика движения на более высоких уровнях управления автоматическое задание...
41493. ТЕХНОЛОГИЯ И НОРМИРОВАНИЕ МАНЕВРОВОЙ РАБОТЫ 293 KB
  Маневрами называются все передвижения подвижного состава групп или отдельных вагонов а также одиночных локомотивов по станционным путям для выполнения различных видов обработки поездов и вагонов обеспечиние погрузки выгрузки и др. Рациональная организация маневров во многом определяет успешную работу станций уровень их перерабатывающей способности и выполнение основного качественного показателя затраты времени на обработку вагонов. Маневры классифицируются по следующим признакам: 1 по характеру; 2 по назначению; 3 по способу...
41494. Технология работы промежуточных станций 180 KB
  Опорные промежуточные станции их эффективность. Для четкой организации работы на промежуточных станциях составляются технологические карты операций которые включают: нормы времени на приготовление поездных маршрутов и станционные интервалы; графики работы со сборными поездами и нормы времени на операции со сборнораздаточными вагонами; нормы времени на маневровые передвижения в пределах станции с пути на путь с разным количеством вагонов и одного локомотива; нормы простоя вагонов под грузовыми операциями и графики обработки вагонов на...