Послідовний метод доступу до файлів на зовнішніх запам’ятовуючих пристроях

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
КН
Кафедра:
Кафедра САПР

Інформація про роботу

Рік:
2009
Тип роботи:
Звіт про виконання лабораторної роботи
Предмет:
Організація баз даних і знань

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти і науки України Національний університет «Львівська політехніка» Кафедра САПР ЗВІТ про виконання лабораторної роботи №1 на тему: «Послідовний метод доступу до файлів на зовнішніх запам’ятовуючих пристроях» з курсу: «Організація баз даних і знань» Львів 2009 Тема роботи Послідовний метод доступу до файлів на зовнішніх запам’ятовуючих пристроях Мета роботи Розглянути органiзацiю i ведення файлiв послiдовного доступу; набути практичнi навички у програмуваннi алгоритмiв роботи з файлами послiдовного доступу. Лабораторне завдання Тема завдання: Ветеринарна лікарня 1. Написати програму, яка реалізує такі функції: 1.1. Друк бази даних. 1.2. Пошук запису за введеним ключем. 1.3. Видалення запису за введеним ключем. 1.4. Вставлення запису. 1.5. Модифікація запису. Короткі теоретичні відомості Будь-який обмiн даними передбачає присутнiсть джерела iнформацiї, каналу передачi та її приймача. У випадку обмiну даними мiж програмою i периферiйним пристроєм одним кiнцем каналу обмiну даними завжди є оперативна пам’ять ПЕОМ. Другий кiнець цього каналу у бiльшостi мов програмування визначений як файл. Поняття файла достатньо широке. Це може бути комунiкацiйний порт, пристрiй друку. У данiй роботi розглядається файл даних. Одним iз головних чинникiв, що впливає на продуктивнiсть програм, якi взаємодiють iз базою даних, є спосiб зберiгання i доступу до файлiв даних: послiдовний, iндексно-послiдовний, індексно-довiльний, прямий, хешування. Усi методи розглядаються за двома критерiями: 1. Ефективнiсть доступу - величина, обернена середнiй кiлькостi фiзичних звертань, необхiдних для логiчного доступу, тобто запиту конкретного запису бази даних. Фiзичнi звертання забезпечують задоволення запиту. Наприклад, якщо для пошуку потрiбного запису система звертається до двох записiв, то ефективнiсть доступу дорiвнює 0,5. 2. Ефективнiсть зберiгання - величина, обернена середнiй кiлькостi байтiв поля вторинної пам’ятi, яка необхiдна для зберiгання одного байта вхiдних даних. Крiм вхiдних даних, пам’ять займають таблицi, керуюча iнформацiя, вiльна пам’ять, яка резервується для розширень, i дiлянка, яка не використовується через фрагментацiю 1. ДОСТУП ДО ЗАПИСІВ Записи у простому послiдовному файлi доступнi лише послiдовно один за одним. Наприклад, можна звернутися до n-го запису тiльки пiсля звертання до 1,2,...,n-1 записiв. Для того, щоб видалити запис з файла, необхiдно створити копiю файла, у якiй цей запис є вiдсутнiм; для того, щоб помiстити запис у файл, також необхiдно створити копiю файла, у яку цей новий запис входить. Щоб змiнити хоча б одне з полiв у записi, необхiдно створити копiю файла, який мiститиме модифiкований запис. При послiдовному методi доступу значення ключiв фiзичних записiв знаходяться у логiчнiй послiдовностi. 1.1. Ефективнiсть доступу. Нехай вибрано один фiзичний запис, i належить вибрати iнший з бiльшим значенням ключа. У найгiршому випадку для вибору потрiбного запису необхiдно переглянути всi записи бази даних, а у кращому достатньо вибрати наступний запис. Для того, щоб виявити необхiдний запис у послiдовному файлi, який складається з N записiв, необхiдно переглянути у середньому N/2 записiв. Це пояснюється так. Нехай здiйснюється достатньо багато випробовувань, пов’язаних iз пошуком у послiдовному файлi випадково вибраних значень ключа. Причому кожний пошук починається з першого запису файла. Тодi для виявлення шуканого запису потрiбно переглянути у середньому половину загальної кiлькостi записiв. 1.2. Ефективнiсть зберiгання. Ефективнiсть використання пам'ятi близька до 100%. Зберiгання фiзичних записiв у логiчнiй послiдовностi можна використовувати для прискорення доступу, якщо перед звертанням до власне записiв бази даних перевiряти значення ключiв. 2.1.3 Алгоритм вставляння запису <зчитати номер запису, який потрiбно вставити><m> <зчитати данi><str> <вiдкрити два файли, файл А - для читання, файл B - для зберiгання модифiкованої iнформацiї> i:=1 доки не кiнець файла А якщо m<>i тодi <зчитати з А, записати в B> i:=i+1 iнакше <записати у В str> якщо m>=i тодi <записати в В str> <закрити файли А, В> <змiнити iм'я з В на А> 1.4. Алгоритм модифiкацiї записiв <зчитати номер запису, який потрiбно модифiкувати><m> <зчитати данi><str> <вiдкрити два файли, файл А - для читання, файл B - для зберiгання модифiкованої iнформацiї> i:=1 доки не кiнець файла А якщо i=m тодi <зчитати з А><sm> <записати в B><str> i:=i+1 iнакше <зчитати з А><sm> <записати у В>< sm> <закрити файли А, В> <змiнити iм'я з В на А> 1.5. Алгоритм видалення запису <зчитати номер запису, який потрiбно видалити><m> <вiдкрити два файли, файл А - для читання, файл B - для зберiгання модифiкованої iнформацiї> i:=1 доки не кiнець файла А якщо i=m тодi <зчитати з А><sm> <записати в B><sm> 2. ГРУПОВЕ ОБРОБЛЕННЯ ПОСЛІДОВНИХ ФАЙЛІВ Якщо необхiдно органiзувати доступ до М записiв послiдовного файла, який складається з N записiв, то звичайно прагнуть не застосовувати методу лiнiйного пошуку. Адже тодi знадобиться застосовувати цей метод М разiв, починаючи кожного разу перегляд файла з першого запису. Всього потрiбно проаналiзувати MN/2 записiв; очевидно, що при великому N на це буде витрачено значний час. Існує ефективнiший метод перегляду файла: лише один раз. Для того, щоб використати цей метод, необхiдно всi значення шуканих первинних ключiв вставити у новий файл. Цей файл звичайно називають файлом повiдомлень, а файл, у якому здiйснюється пошук, головним файлом. Головний файл i файл повiдомлень повиннi бути впорядкованi за одним ключем. Спершу з файла повiдомлень зчитується перше значення первинного ключа i за методом лiнiйного пошуку у головному файлi шукається запис, що йому вiдповiдає. Потiм зчитується друге значення первинного ключа, i пошук у головному файлi продовжується, починаючи з того запису, на якому вiн припинився. Цей процес послiдовно повторюється для всiх значень первинного ключа з файла повiдомлень. Текст програми: #include <iostream.h> #include <conio.h> #include <string.h> #include <stdio.h> #include <math.h> #include <stdlib.h> #define mainSize (sizeof (animalRecord) + 2*9) char mainPath[256] = "dbase.pdb"; char tempPath[] = "$temp.pdb"; char searchPath[] = "$srch.pdb"; char groupPath[] = "$group.tdb"; char keyTab = 1; FILE *dbFile = NULL, *tempFile = NULL, *groupFile = NULL; class animalRecord { public: int ID; int Age; char Pet[40+2]; char ownerName[40+2]; char Illness[40+2]; int price; char notes[40+2]; int isSet; int errorcode; int toDo; void readFile(FILE *CUR = NULL, int toDo = 0); void writeToFile(FILE *CUR = NULL, int toDo = 0); void goToKey(FILE *CUR = NULL); animalRecord(); }; animalRecord::animalRecord() { ID = -1; Age = 0; strcpy (Pet,"-"); strcpy (Name,"-"); strcpy (Illness,"-"); price = 0; strcpy (notes,"-"); errorcode = toDo = isSet = 0; } void animalRecord::writeToFile(FILE* CUR, int toDo) { if (CUR == NULL) return; double cur = 0; int i = 0; cur = ftell(CUR); for (i=0;i<mainSize;i++) { fseek (CUR,cur+i,SEEK_SET); fprintf(CUR," "); } fseek(CUR,cur,SEEK_SET); if(toDo) fprintf(CUR,"%c\n%d\n%d\n%s\n%s\n%s\n%d\n%s\n%d\n",keyTab, this->ID, this->Age, this->Pet, this->Name, this->Illness, this->price, this->notes, this->toDo); else fprintf(CUR,"%c\n%d\n%d\n%s\n%s\n%s\n%d\n%s\n",keyTab, this->ID, this->Age, this->Pet, this->Name, this->Illness, this->price, this->notes); } void animalRecord::readFile(FILE *CUR, int toDo) { animalRecord buf=animalRecord(); int eofflag=0, l, read=0; char cbuf, key=0; buf.isSet=0; do { if(feof(CUR)) { eofflag=1; break; } fscanf(CUR,"%c",&key); } while(key!=keyTab); if(eofflag) { if(!read) { buf.errorcode=1; *this = buf; return; } } //Reading record -------------------------------------------------------------- fscanf(CUR,"\n%d\n",&buf.ID); fscanf(CUR,"%d\n",&buf.Age); for(l=0, fscanf(CUR,"%c",&cbuf);cbuf!='\n';l++) {buf.Pet[l]=cbuf; fscanf(CUR,"%c",&cbuf);} buf.Pet[l]='\0'; for(l=0, fscanf(CUR,"%c",&cbuf);cbuf!='\n';l++) {buf.Name[l]=cbuf; fscanf(CUR,"%c",&cbuf);} buf.Name[l]='\0'; for(l=0, fscanf(CUR,"%c",&cbuf);cbuf!='\n';l++) {buf.Illness[l]=cbuf; fscanf(CUR,"%c",&cbuf);} buf.Illness[l]='\0'; fscanf(CUR,"%d\n",&buf.price); for(l=0, fscanf(CUR,"%c",&cbuf);cbuf!='\n';l++) {buf.notes[l]=cbuf; fscanf(CUR,"%c",&cbuf);} buf.notes[l]='\0'; if (toDo) fscanf(CUR,"%d\n",&buf.toDo); buf.isSet=1; *this = buf;} void animalRecord::goToKey(FILE *CUR) {int i=0,a;float ad; char key; if((ftell(CUR))>0) fseek(CUR,-1,SEEK_CUR); else{return;} do {ad = ftell(CUR); fscanf(CUR,"%c",&key); fseek(CUR,ad,SEEK_SET); if(key=='\n') a=-2; else a=-1; fseek(CUR,a,SEEK_CUR); }while(key!=keyTab); fseek(CUR,1,SEEK_CUR);} //------------------------------------------------------------------------------ int reccmp(char str1[47], char str2[47], int count); void New(); void Open(); char* SetStr(int); animalRecord Set (animalRecord set = animalRecord () ); void Insert(animalRecord sav=animalRecord(),char* mainPath=::mainPath); void Delete(int ID=-1); void Modify (); void Find (); void Print (); void GroupWork(); int main() {textmode(64); clrscr(); do { cout<<"\n1. Create new DataBase"<< "\n2. Open the DB"<< "\n3. Insert"<< "\n4. Remove"<< "\n5. Edit"<< "\n6. Search..."<< "\n7. Print all to monitor"<< "\n8. Group work"<< "\n9. Quit\n"<< "Vybir: "; switch(getch()) {case '1': clrscr();New(); break; case '2': clrscr();Open(); break; case '3': clrscr();Insert(); break; case '4': clrscr();Delete(); break; case '5': clrscr();Modify(); break; case '6': clrscr();Find(); break; case '7': clrscr();Print(); break; case '8': clrscr();GroupWork();break; case '9': clrscr();return 0; default: clrscr();cout<<"Your choise is incorrect!\n";break;} }while(1);} void New() {cout<<"Enter path: "; cin>>mainPath; if((dbFile = fopen (mainPath, "w+"))== NULL) {cout<<"Can't create!\n";return;} rewind(dbFile); printf("%s successfully created.\n\r",mainPath); } void Open() {cout<<"Enter path: "; cin>>mainPath; if((dbFile = fopen (mainPath, "r+"))== NULL) //Pomylka {cout<<"Can't open!\n";return;} cout<<"The database "<<mainPath<<" is opened...\n";} animalRecord Set (animalRecord set) {clrscr(); if (!set.isSet) set.ID=0; do {cout<<"Enter fields:\n\n"; cout<<"1. ID: "<<set.ID<<"\n"; cout<<"2. Age: "<<set.Age<<"\n"; cout<<"3. Pet Name: "<<set.Pet<<"\n"; cout<<"4. Name: "<<set.Name<<"\n"; cout<<"5. Illness: "<<set.Illness<<"\n"; cout<<"6. price: "<<set.price<<"\n"; cout<<"7. notes: "<<set.notes<<"\n\n"; cout<<"8. Ready\n"; cout<<"9. Cansel\n\n"; cout<<"Choice:\n"; switch (getch()) {case '1': cout<<"1. ID: ";cin>>set.ID;clrscr();break; case '2': cout<<"2. Age: ";cin>>set.Age;clrscr();break; case '3': cout<<"3. Pet: ";strcpy(set.Pet,SetStr(40));clrscr();break; case '4': cout<<"4. Name: ";strcpy(set.Name,SetStr(40));clrscr();break; case '5': cout<<"5. Illness: ";strcpy(set.Illness,SetStr(40));clrscr();break; case '6': cout<<"6. Price: ";cin>>set.price;clrscr();break; case '7': cout<<"7. Notes: ";strcpy(set.notes,SetStr(40));clrscr();break; case '8': clrscr();set.isSet=1;return set; case '9': clrscr();set.isSet=0;return set; default: clrscr();cout<<"Nepravyl'nyj vybir!\n";} }while(1);} void Insert(animalRecord sav, char mainPath[60]) { if (dbFile == NULL) {cout<<"The base is not opened!\n";return;}//Pomylka animalRecord ins = animalRecord(); if(sav.isSet)ins=sav; else ins=Set(animalRecord()); animalRecord buf=animalRecord(); if(ins.isSet==0){printf("Couldn't insert!\n");return;} if(ins.ID<0){printf("Couldn't insert!\n");return;} if((tempFile=fopen(tempPath,"w"))==NULL){printf("Couldn't insert!\n");return;}; rewind(tempFile); rewind(dbFile); int insert=0; do{ if(ins.toDo) buf.readFile(dbFile,1); else buf.readFile(dbFile); if(buf.errorcode==1) {if(!insert) {if(ins.toDo) ins.writeToFile(dbFile,1); else ins.writeToFile(dbFile); fclose(tempFile); remove(tempPath);} if(insert) {fclose(dbFile); fclose(tempFile); remove(mainPath); rename(tempPath,mainPath); dbFile=fopen(mainPath,"r+");} fflush(dbFile); printf("Record %d successfully inserted.\n",ins.ID);return;} //Kopiyuvanna doky ne znajdeno misce vstavky a takozh pisla vsyavky if((ins.ID > buf.ID)||(insert)) if(ins.toDo) buf.writeToFile(tempFile,1); else buf.writeToFile(tempFile); //nevirne id if(ins.ID==buf.ID){printf("Couldn't insert!\n"); fclose(tempFile); remove(tempPath); fclose(dbFile); dbFile=NULL; dbFile=fopen(mainPath,"r+"); return;} //Vstavka if((ins.ID < buf.ID)&&(!insert)) { if(ins.toDo) { ins.writeToFile(tempFile,1); buf.writeToFile(tempFile,1);} else{ ins.writeToFile(tempFile); buf.writeToFile(tempFile);} insert=1;} }while(1);} void Delete(int ID) { if (dbFile == NULL) {cout<<"The base isn't opened!\n";return;}//Pomylka if(ID!=-1)goto dellab; ID=0; while(1) {cout<<"1. Enter ID: "<<ID<<"\n"; cout<<"2. Remove\n"; cout<<"3. Cansel\n\nVybir:\n"; switch(getch()) {case '1': cout<<"1. Enter ID: ";cin>>ID;clrscr();break; case '2': clrscr();goto dellab; case '3': clrscr();return; default: clrscr();cout<<"Incorrect choice\n";break;} } dellab:; animalRecord buf=animalRecord(); if((tempFile=fopen(tempPath,"w"))==NULL){printf("Couldn't remove the record!\n");return;}; rewind(tempFile); fclose(dbFile); dbFile=fopen(mainPath,"r+"); // fflush(dbFile); rewind(dbFile); int del=0; do{buf.readFile(dbFile); if(buf.errorcode==1) {if(!del) {printf("Couldn't remove the record!\n"); fclose(tempFile); remove(tempPath); return;} if(del) {fclose(dbFile); fclose(tempFile); remove(mainPath); rename(tempPath,mainPath); dbFile=fopen(mainPath,"r+");} printf("Record %d has been removed.\n",ID); return;} //Kopiyuvanna doky ne znajdeno misce vstavky a takozh pisla vsyavky if((ID > buf.ID)||(del)) buf.writeToFile(tempFile); //virne id if(ID==buf.ID){del=1;} if( (ID < buf.ID)&&(!del) ) {printf("Couldn't remove the record!\n"); fclose(tempFile); remove(tempPath); return;} }while(1);} void Modify() { if (dbFile == NULL) {cout<<"The base isn't opened!\n";return;}//Pomylka int ID=0; int read=0; animalRecord buf=animalRecord(), mod=animalRecord(); while(1) {cout<<"1. Enter ID: "<<ID<<"\n"; cout<<"2. Edit\n"; cout<<"3. Cansel\n\nChoice:\n"; switch(getch()) {case '1': cout<<"1. Enter ID: ";cin>>ID;clrscr();break; case '2': clrscr();goto readlab; case '3': clrscr();return; default: clrscr();cout<<"Incorrect choice\n";break;}} readlab: rewind(dbFile); do{ buf.readFile(dbFile); if(buf.errorcode==1) {if(!read) {printf("Couldn't Edit!\n"); return;} } //virne id if(ID==buf.ID) {read=1; mod=Set(buf); Delete(mod.ID); Insert(mod); clrscr(); printf("Record %d is edit.\n",mod.ID); return;} if( (ID < buf.ID)&&(!read) ) {printf("Couldn't Edit!\n"); return;} }while(1);} void Find() {FILE *T; int fnd=0; clrscr(); if (dbFile == NULL) {cout<<"The base is not opened!\n";return;}//Pomylka int tofin=0;char k; animalRecord set = animalRecord(),buf = animalRecord(); animalRecord tmp; T = fopen (searchPath,"w+"); cout<<"Search by:\n\n"; cout<<"1. ID "<<"\n"; cout<<"2. Age "<<"\n"; cout<<"3. Pet "<<"\n"; cout<<"4. Name "<<"\n"; cout<<"5. Illness "<<"\n"; cout<<"6. Price "<<"\n"; cout<<"7. Notes "<<"\n\n"; cout<<"8. Cansel\n\n"; cout<<"Choice:\n"; k = getch(); switch (k) {case '1': cout<<"1. ID: ";cin>>set.ID;clrscr();break; case '2': cout<<"2. Age: ";cin>>set.Age;clrscr();break; case '3': cout<<"3. Pet: ";strcpy(set.Pet,SetStr(40));clrscr();break; case '4': cout<<"4. Name: ";strcpy(set.Name,SetStr(10));clrscr();break; case '5': cout<<"5. Illness: ";strcpy(set.Illness,SetStr(10));clrscr();break; case '6': cout<<"6. Price: ";cin>>set.price;clrscr();break; case '7': cout<<"7. Notes : ";strcpy(set.notes,SetStr(40));clrscr();break; case '8': clrscr();return; default: clrscr();cout<<"Incorrect choice!\n";return;} tmp = set; tofin = k - '1'; rewind(dbFile); do{buf.readFile(dbFile); if(buf.isSet) switch(tofin) { case 0: if(tmp.ID==buf.ID) {fnd++; buf.writeToFile(T);}break; case 1: if(tmp.Age==buf.Age) {fnd++; buf.writeToFile(T);}break; case 2: if(!(reccmp(tmp.Pet,buf.Pet,strlen(tmp.Pet)))) {fnd++; buf.writeToFile(T);}break; case 3: if(!(reccmp(tmp.Name,buf.Name,strlen(tmp.Name)))) {fnd++; buf.writeToFile(T);}break; case 4: if(!(reccmp(tmp.Illness,buf.Illness,strlen(tmp.Illness)))) {fnd++; buf.writeToFile(T);}break; case 5: if(tmp.price==buf.price) {fnd++; buf.writeToFile(T);}break; case 6: if(!(reccmp(tmp.notes,buf.notes,strlen(tmp.notes)))) {fnd++; buf.writeToFile(T);}break; }fflush(T); }while(buf.errorcode!=1); clrscr(); cout<<fnd<<" results\n"; rewind(T); do {set.readFile(T); if(set.ID!=-1){ cout<<"ID: "<<set.ID<<"\n"; cout<<"Age: "<<set.Age<<"\n"; cout<<"Pet: "<<set.Pet<<"\n"; cout<<"Name: "<<set.Name<<"\n"; cout<<"Illness: "<<set.Illness<<"\n"; cout<<"Price: "<<set.price<<"\n"; cout<<"Notes: "<<set.notes<<"\n\n";} }while(set.errorcode!=1); cout<<"Press enter...";while(getch()!=13);clrscr(); fclose(T);} void Print() {animalRecord set; if (dbFile == NULL) {cout<<"The base is not opened!\n";return;}//Pomylka rewind(dbFile); do {set.readFile(dbFile); if(set.ID!=-1){ cout<<"ID: "<<set.ID<<"\n"; cout<<"Age: "<<set.Age<<"\n"; cout<<"Pet: "<<set.Pet<<"\n"; cout<<"Name: "<<set.Name<<"\n"; cout<<"Illness: "<<set.Illness<<"\n"; cout<<"Price: "<<set.price<<"\n"; cout<<"Notes: "<<set.notes<<"\n\n";} }while(set.errorcode!=1); cout<<"Press enter...";while(getch()!=13);clrscr(); } char* SetStr(int count) {char k; int curpos=0; char* str = (char*) malloc (count*sizeof(char)); do {k=getche(); switch (k) {case 8: cprintf(" %c",8);curpos--;if(curpos<0)curpos=0;str[curpos]='\0';break;//backspace case 13: if(curpos==0){str[curpos]='-';curpos++;}str[curpos]='\0';break; case 27: strcpy(str,"-");k=13;break; default: str[curpos]=k; curpos++;} if(curpos>=count-2) {k=13;str[curpos]=k; curpos++;} }while(k!=13); return str;}
Антиботан аватар за замовчуванням

17.07.2020 10:07-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!