10. Лабораторна робота № 10
Робота з файлами
Мета: Набуття навичок з використання в програмах файлів.
10.1. Організація файлів і їх типи
Файл – це впорядкований набір даних, який розрізняється за іменем і може зберігатись на будь-якому доступному носію інформації: дискеті, вінчестері, компакт-диску та ін. Visual Basic має гнучкі засоби для роботи з файлами. Він підтримує різні способи зчитування вхідних даних і формування результатів у вигляді файлів. Дозволяє роботу з усіма відомими типами організації файлів, а саме файлами послідовного й прямого доступу, а також двійковими файлами.
Робота з файлами у Visual Basic реалізується з використанням певних ресурсів операційної системи Windows, з допомогою яких проводиться обмін даними між диском і оперативною пам’яттю. У разі створення файлу операційна система Windows виділяє йому певний канал вводу-виводу, який закріплюється за даним файлом на весь час роботи з ним. Система Windows дозволяє одночасно виділити до 512 каналів вводу-виводу. Номер вільного каналу визначається з допомогою функції FreeFile, результатом звертання до якої є цілочислове значення, що відповідає номерові незайнятого каналу вводу-виводу.
Для виділення ресурсів операційної системи, необхідних для налагодження доступу до файлу в середовищі Visual Basic і закріплення за ним певного каналу вводу-виводу, використовують оператор Open. Формат оператора Open залежить від типу файлу.
10.1.1. Файли послідовного доступу
Файл послідовного доступу – це текстовий файл у вигляді набору рядків тексту, кожен рядок якого завершується символами кінця рядка і переходу на наступний. Після останнього рядка файлу стоїть мітка кінця файлу. Для відкриття файлу послідовного доступу використовується оператор Open, формат якого має вигляд
Open < ім’я файлу> For [Input | Output | Append] As <номер>
В цьому операторі ім’я файлу – це повне ім’я файлу на диску, а номер – номер незайнятого каналу вводу-виводу. При відкритті файлу послідовного доступу необхідно ще вказати тип операції, а саме, з якою метою його відкриваємо – для зчитування даних чи запису (формування файлу). Зрозуміло, що у разі відкриття файлу в режимі зчитування він повинен фізично існувати. Спроба відкрити для зчитування неіснуючий файл зумовлює виникнення помилки, яка спричиняє припинення виконання програми.
Для зчитування даних з файлу послідовного доступу використовуються оператори Line Input і Input, а також функція Input$. Оператор Line Input дозволяє зчитати з файлу послідовного доступу рядок в цілому. При цьому символи завершення рядка і його переводу вилучаються. Формат оператора має вигляд
Line Input # Nf , <змінна>
Тут Nf – номер каналу, на якому відкрито файл в режимі зчитування, а змінна – ім’я символьної змінної, якій присвоюється значення зчитаного рядка.
Оператор Input дозволяє зчитувати значення даних по одному або згідно списку в порядку їх слідування у файлі, його формат має вигляд
Input # Nf, <список>
де Nf – номер файлу, а список – це перелік імен змінних, значення яких зчитується. При цьому тип змінних повинен співпадати з типом даних, які зчитується з файлу. Імена змінних в списку як і дані у файлі повинні відокремлюватись одне від одного комами.
Слід зазначити, що спроба зчитати рядок чи окреме значення, якого у файлі немає, приводить до помилкової ситуації. Середовищем Visual Basic це трактується як спроба зчитати мітку кінця файлу. Для запобігання такої ситуації необхідно слідкувати за зчитуваними даними, а саме контролювати їх кількість, коли вона відома, або з допомогою функції EOF (End Of File) передбачити перевірку наявності мітки кінця файлу. Формат функції EOF має вигляд
EOF (<номер каналу>)
де аргумент функції вказує номер виділеного для файлу каналу вводу-виводу, наприклад, EOF(Nf). Ця функція набуває значення True при спробі зчитати мітку кінця файлу і її значення дорівнює False, якщо ще не всі дані зчитано.
Функція Input$ призначена для зчитування з файлу послідовного доступу певної кількості символів. Формат цієї функції має такий вигляд
<змінна> = Input$(<кількість>, <номер>)
де кількість вказує число символів, що зчитується з файлу відкритого на каналі з зазначеним номером. Для визначення кількості символів у файлі можна використати функцію LOF (Length Of File). Наприклад, функція LOF(Nf) визначає кількість байтів, яку займають дані у файлі, який відкрито на каналі вводу-виводу з номером Nf. Слід зазначити, що функція LOF набуває значення числа всіх наявних у файлі символів, включаючи символи завершення рядка та переходу на наступний.
Для запису даних у файл послідовного доступу його необхідно попередньо відкрити в режимі формування Output або поповнення Append. При відкритті файлу в режимі Output створюється новий файл з вказаним в операторі Open іменем, якщо файл з зазначеним іменем вже існує, то він затирається. Це означає, що при відкритті файлу в режимі Output можлива втрата даних. Тому на випадок поповнення файлу даними передбачено режим Append. При відкритті файлу в цьому режимі наявні в ньому дані не затираються і надається можливість дописати нові дані вкінець файлу.
Запис даних у файл послідовного доступу проводиться операторами Print і Write. Оператор Print використовується для форматованого запису даних у файл. Формат оператора Print має вигляд
Print #< номер>, {[Spc(n) | Tab{(m)}] ; }<список> {[ , | ; ]}
де список задає перелік виразів, значення яких записується у файл, який попередньо відкрито на каналі вводу-виводу з вказаним номером. Для відокремлення елементів у списку можна використовувати кому або крапку з комою. Необов’язкові функції Spc i Tab використовуються для визначення позиції виводу. Аргумент n функції Spc задає кількість пробілів (пропусків), які розділяють значення, що записуються у файл. Функція Tab визначає позицію в рядку, з якої записується наступне значення. Функції форматування Spc i Tab можуть також застосовуватись і як окремі елементи в списку для визначення позицій запису конкретних значень.
Оператор Write призначений для неформатованого запису даних у файл. Він використовується для запису у файл даних, які планується згодом зчитувати оператором Input. Формат оператора Write має вигляд
Write # <номер>, <список>
де список, як і в операторі Print, є переліком виразів, значення яких записується у файл. Для відокремлення елементів у списку можна використовувати кому або крапку з комою. Відмінність оператора Write від Print полягає в тому, що він комами відділяє окремі значення, які записуються у файл, тобто представляє їх у вигляді, придатному для подальшого їх зчитування оператором Input.
При завершенні роботи з файлом його необхідно закрити. Для закриття файлу використовується оператор Close, формат якого має вигляд
Close {{#}<номер>}{,{#}<номер 2>}{, . . .{#}<номер k>}}
де номери вказують номери каналів вводу-виводу, на яких відкрито файли, робота, з якими припиняється. Якщо в операторі Close не вказано жодного номера, то закриваються всі відкриті в програмі на даний момент файли.
10.1.2. Файли прямого доступу
Файл прямого доступу – це впорядкований набір записів, тобто даних фіксованої структури. Відкриття файлу прямого доступу реалізується оператором Open, синтаксис якого має вигляд
Open <ім’я файлу> {For Random} {Access <доступ>}{<блокування>} As {#} <номер>
{Len =<довжина запису>}
де For Random, Access, Len – зарезервовані слова.
Зарезервовані слова For Random вказують на відкриття файлу прямого доступу, вони приймаються за замовчуванням. Ім’я файлу може задаватись символьною константою або змінною, значення якої відповідає повному імені файлу. Номер – це номер каналу вводу-виводу, на якому відкривається файл. Частина Len визначає довжину запису в байтах, яка задається значенням арифметичного виразу, яке може знаходитись в межах від 1 до 32767 байтів. За замовчуванням довжина запису приймається в 128 байтів. Умовно файл прямого доступу можна представити як віртуальний масив записів, в якому номер запису відповідає індексу.
Необов’язкова чистина Access <доступ> в операторі Open визначає режим доступу до файлу, а блокування визначає допустимі операції з файлом, які одночасно дозволено для інших користувачів мережі.
Для закриття файлів прямого доступу також використовується оператор Close.
Зчитування й запис даних у файл прямого доступу реалізується операторами Get i Put, формат яких має вигляд
Get #<номер файла>, {<номер запису>}, <ім’я змінної>
Put #<номер файла>, {<номер запису>}, <ім’я змінної>
Оператор Get використовується для зчитування даних з файлу, а оператор Put для поміщення запису у файл. При виконанні оператора Get вказаній змінній надається значення запису розміщеного у файлі за заданим номером. Номер запису може задаватись арифметичним виразом, значення якого повинно належати діапазону від 1 до 2247483647. Якщо номер запису опущено, то операція зчитування чи занесення даних у файл проводиться відносно поточного запису.
Особливості виконання операцій з файлом прямого доступу розглянемо на прикладі програми, яка формує файл прямого доступу з відомостями про успішність студентів і при потребі виводить список студентів, середній бал успішності яких вищий за заданий. Можливий вигляд робочого вікна цієї програми показано на рис. 10.1. Для зберігання інформації про успішність студентів використаємо файл прямого доступу з записами, які включають три поля:
Private Type Student
Prizv As String * 15
Imia As String * 15
SeredBal As Single
End Type
Натиснення кнопки "Формування файлу" передбачає компонування значень окремих записів і занесення їх у файл. Відповідна процедура реакції може включати такі оператори:
Dim Stud_Kt As Student
Private Sub Formuvannia_Click()
Dim But As Integer
Dim Nf As Integer
Nf = FreeFile
Open "c:\Visual\Kt_4" For Random As Nf Len = Len(Stud_Kt)
M: Stud_Kt.Prizv = InputBox("Введіть прізвище ")
Stud_Kt.Imia = InputBox("Введіть ім'я ")
Stud_Kt.SeredBal = InputBox("Введіть середній бал ")
Put #Nf, , Stud_Kt
But = vbYesNo + vbQuestion + vbDefaultButton1
If MsgBox("Ввід даних продовжити? ", But) = vbYes Then GoTo M
Close Nf
End Sub
В наведеній процедурі для занесення записів у файл використано оператор Put без явного задання номера запису. Повторне виконання цього оператора послідовно поміщає в файл вказані записи починаючи з першої.
Натиснення кнопки "Пошук даних" забезпечує вибір з раніше сформованого файлу даних про студентів, середній бал яких вищий від заданого. Варіант процедури реакції на натиснення даної кнопки може мати вигляд:
Private Sub Poshuk_Click()
Dim Nf As Integer, Bal As Single, P As String
Bal = Val(SBal.Text)
Nf = FreeFile
Open "c:\Visual\Kt_4" For Random As Nf Len = Len(Stud_Kt)
Do Until EOF(Nf)
Get #Nf, , Stud_Kt
' Послідовне зчитування записів з файлу
If Stud_Kt.SeredBal > Bal Then
' Перевірка середнього балу
P = Stud_Kt.Prizv + " " + Stud_Kt.Imia + Str(Stud_Kt.SeredBal)
Text1.Text = Text1.Text + vbCrLf + P
' Відображення даних, які задовольняють середньому балу
End If
Loop
Close Nf
End Sub
Дана процедура послідовно зчитує всі наявні у файлі записи (оператор Get, без явного вказання номера запису). Перевірка в циклі Until наявності мітки кінця файлу запобігає спробі зчитування неіснуючого запису подібно до того, як це було організовано у раніше розглянутому прикладі для файлу послідовного доступу. Щоразу після зчитування запису перевіряється значення середнього балу й у випадку, якщо він вищий від заданого, то дані про студента відображаються в текстовому полі Text1.
10.1.3. Двійкові файли
Двійкові файли забезпечують доступ до окремих байтів. За організацією доступу їх можна розглядати як частковий різновид файлів прямого доступу. Двійкові файли часто використовують для зчитування даних з файлу, структура якого невідома. Формат оператора відкриття двійкового файлу має вигляд:
Open <ім’я файлу> For Binary {Access <доступ>}{<блокування>} As {#} <номер>
де зарезервоване слово Binary вказує на відкриття двійкового файлу. Для запису і зчитування даних з двійкового файлу використовуються оператори Put i Get, формат яких замість номеру запису передбачає номер байту. Наприклад, оператор Get
Dim S As String*1
Get # Nf, 15, S
зчитує з файлу відкритого на каналі вводу-виводу з номером Nf п’ятнадцятий байт і присвоює його змінній S.
Для закриття двійкового файлу також використовується оператор Close.
10.2. Завдання
Програму, розроблену при виконанні лабораторної роботи № 6, доповнити так щоб вона при виконанні варіантів з першого по сьомий дані зберігала у файлі послідовного доступу, а з восьмого по чотирнадцятий у файлі послідовного доступу.