68972

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

Лекция

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

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

Украинкский

2014-09-28

58 KB

10 чел.

Лекція № 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. Він дозволяє зберігати максимальну кількість символів, які можуть перетворюватися при виконанні операцій введення-виведення.


 

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

27801. СИСТЕМА РАБОТЫ С ОДАРЁННЫМИ ДЕТЬМИ В МОУ СОШ № 3 с. КИТАЕВСКОГО ВО ВНЕУРОЧНОЕ ВРЕМЯ 40.19 KB
  Вовлечение учащихся в систему дополнительного образования. Деятельность научного общества учащихся Олимп в которое входят предметные секции. Материальная поддержка талантливых и одарённых детей поездка в Москву на Всероссийский конкурс творческих работ учащихся посвящённый 75летию Д. Это позволяет увидеть оригинально мыслящих учащихся уделять внимание развитию их способностей.
27802. Работа учителей иностранного языка с одаренными детьми 181.5 KB
  Алексин Тульской области август 2010 года Слайд 2 В настоящее время одним из приоритетных направлений государственной политики в области образования является работа с одаренными детьми. Слайд 3 Наличие способных учащихся в школе реализация целевой программы Наша новая школа подчёркивают актуальность и необходимость программы развития одарённых детей. Слайд 4 Работа учителей иностранного языка с одаренными детьми В каждом классе есть учащиеся обладающие особыми способностями в изучении иностранных языков. Летний профильный лагерь...
27804. Принципы организации и функции детского досуга 65.5 KB
  Досуг детей подростков и юношества развивается по своим законам принципам теоретически обоснованным и апробированным на практике.Принцип всеобщности и доступности возможность приобщения вовлеченности всех детей подростков и юношества в сферу деятельности досуговых учреждений с целью удовлетворения творческих потенций подрастающего поколения их досуговых запросов и интересов. Принцип самодеятельности основывается на творческой активности увлеченности и инициативе детей подростков и юношества с одной стороны и их поощрении...
27805. Ресоциализация 32.5 KB
  в собственных глазах подростка должна быть развенчана вся атрибутика той уличной субкультуры которая до сих пор для него имела исключительную значимость. В это время становится очевидной инерционность прежних социальных установок подростка оценок его поведения общественного мнения в школе в кругу друзей. Коррекция имеет следующие функции: восстановительную предполагающую восстановление тех положительных качеств которые преобладали у подростка до появления трудновоспитуемости обращение к памяти подростка о его добрых делах; ...
27806. Социально - психологический портрет современного подростка 32.5 KB
  Подростковый возраст как наиболее сложный этап в развитии ребенка Подростковый возраст период жизни человека от детства к юности в традиционной классификации от 1112 до 1415 лет. [11] Подростковый возраст протекает очень бурно самый затяжной и самый острый. Можно говорить о трех кризисах которые сливаются воедино и переживаются подростками а значит о трех группах причин которые делают возраст труднее. Возрастает контроль над инстинктом эмоциями.
27808. ЭТИЧЕСКИЕ НОРМЫ ПОВЕДЕНИЯ ПСИХОЛОГОВ-КОНСУЛЬТАНТОВ В ОБЛАСТИ ИНДИВИДУАЛЬНОГО И СЕМЕЙНОГО ПСИХОЛОГИЧЕСКОГО КОНСУЛЬТИРОВАНИЯ 26.49 KB
  Этические нормы устанавливают обязательные правила профессиональной психологической деятельности психологаконсультанта. ЭТИЧЕСКИЕ НОРМЫ Общие нормы Границы компетентности Психологиконсультанты занимаются профессиональной деятельностью только в границах своей компетентности которая определяется образованием формами повышения квалификации и соответствующим профессиональным опытом. Психологиконсультанты осуществляют профессиональную деятельность в новых областях или используют новые методики только после их соответствующего изучения...
27809. Усыновление 44.08 KB
  Рассмотрение дел об установления усыновления ребенка производится судом в порядке особого производства по правилам предусмотренным гражданским процессуальным законодательством. Права и обязанности усыновители и усыновленного ребенка статья 137 настоящего Кодекса возникают со дня вступления в законную силу решения суда об установлении усыновления ребенка. Суд обязан в течение трех дней со дня вступления в законную силу решения суда об установлении усыновления ребенка направить выписку из этого решения суда в орган записи актов...