Сидоров А.О / ос6
.docx
Министерство образования Республики Беларусь
Белорусский Национальный Технический Университет
Факультет информационных технологий и робототехники
Кафедра «Программное обеспечение вычислительной техники
и автоматизированных систем»
Отчёт
по лабораторной работе № 6
по дисциплине «Операционные системы»
тема: «Основы файлового ввода-вывода в Linux:использование системных вызовов»
Исполнитель: |
|
студент группы 10702112 Сидоров А.О. |
Преподаватель: |
|
Радкевич А.С. |
2013-2014 учебный год
ЛАБОРАТОРНАЯ РАБОТА № 6
Основы файлового ввода-вывода в Linux:использование системных вызовов
Цель работы
Основные системные вызовы для взаимодействия с файловой системой и научиться использовать низкоуровневый ввод-вывод в своей работе.
Требования
1) С использованием низкоуровневого ввода-вывода (т.е. системных вызовов ядра ОС Linux) разработать модульное консольное приложение согласно варианту задания А, B и C.
2) Для повышения производительности программы использовать функции для динамического выделения памяти языка программирования С/C++.
3) Для компиляции, компоновки и выполнения программы использовать утилиту make.
4) Для каждой бригады необходимо выполнить задание А и B полностью и один вариант з задания C
Индивидуальное задание:
Задание A
Расширить программу, разработанную при выполнении лабораторной ра-
боты No 5, функционалом, который бы позволял читать размерность и содер-
жимое матрицы из одного файла, а также выводить конечные результаты в
другой файл. Входной файл должен содержать совокупность строк. Строка
файла содержит строку матрицы. Предусмотреть как ручное создание файла
и его заполнение, так и генерацию файла в автоматическом режиме.
Как бы вы модернизировали задание В лабораторной работы No 5 используя
низкоуровневый ввод-вывод? (Можно дописать соответствующий модуль.)
Задание B
-
Разработать программу-тест, которая для своей работы использует только системные вызовы и предоставляет следующие возможности:
-
создание любого файла для записи и чтения; уничтожение указанного файла;
-
создание (уничтожение) и чтение любого каталога;
-
получение данных о файлах;
-
запись (чтение) в файл информации, которая включает в себя все доступные примитивные типы данных языка С/С++, а также текстовых данных(не менее трёх строк).
Задание C
Прочитать текст С программы и удалить из него все “лишние” пробелы и табуляции,только необходимые для разделения операторов.
Ход выполнения лабораторной работы:
-
В текстовом редакторе gedit набрал исходный код решения задания на языке программирования С++ и сохранил исходник. Программа состоит из следующих файлов:
-
function.h – файл заголовка, в котором описаны прототипы функций.
-
function.cc – файл реализации функций;
-
test.cc – файл, в котором описана главная функция программы main;
-
В папке с программой создал make-файл.
-
Запустил терминал Linux и с помощью команды cd перешёл в папку местонахождения исходных кодов программы.
-
Для компиляции программы использовал утилиту make и созданный make-файл.
Результаты выполнения лабораторной работы:
Рисунок 1 — Использование утилиты make
Рисунок 2 — Выполнение программы
Что я освоил в процессе выполнения лабораторной работы:
-
Изучил основные системный вызовы для низкоуровневой с каталогами и файлами,такие как:
mkdir - создание каталога
rmdir - удаление каталогов
opendir - oткрывает дескриптор каталога
closedir - oсвобождает дескриптор каталога
unlink - удаляет указанный файл из каталога
stat - вносит в структуру, на которую указывает statbuf, информацию, содержащуюся в файле, связанном с указателем filename.
readdir -получить элемент каталога по его дескриптору
-
Изучил основные системный вызовы для низкоуровневой с файлом,такие как:
open - открывает файл с указанными флагами открытия и указанным режимом записи.
read - системный вызов читает данные из файла в буфер (тип void*) указанное в последнем аргументе количество байт.
write - записывает в файл определенное в третьем аргументе количество байт из буфера.
close - системный вызов закрывает файл (освобождает дескриптор).
сreat - предоставляет возможность создания новых файлов или перезаписи старых
Выводы:
-
Для повышения производительности программы используются функции для динамического выделения памяти.
-
Основными системными вызовами для низкоуровневой работы являются: mkdir, rmdir, chdir, opendir, closedir, readdir, readlink, link, unlink,stat,open, creat, write, read, close.
ПРИЛОЖЕНИЕ A
Листинг исходного кода программы
Файл functions.h
#ifndef function_H
#define function_H
int polz(int **a,int N,int M);
void print(int **a, int n, int m);
int generator(int **a,int N,int M);
bool LocalMinimum(int **a, int x, int y, int maxX, int maxY);
void find(int **a, int maxX, int maxY);
void file(int **p,int N,int M);
#endif
Файл functions.cc
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "function.h"
using namespace std;
void file(int **p,int N,int M)
{
mode_t fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
int fflags = O_WRONLY | O_CREAT |O_TRUNC;
int fd=open("file.out",fflags, fmode);
if (fd < 0)
{
fprintf (stderr, "Не могу открыть файл!\n");
exit (2);
}
write(fd,&N,sizeof(N));
write(fd,&M,sizeof(M));
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
write(fd,&p[i][j],sizeof(p[i][j]));
}
}
close(fd);
}
int polz(int **a,int N,int M)
{
int i,j;
for (i=0; i<N; i++)
for (j=0; j<M; j++)
{
cin>>a[i][j];
}
return 0;
}
void print(int **a, int n, int m)
{
int i, j;
cout << "Матрица:" << endl;
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
cout << a[i][j] << " ";
cout << endl;
}
}
int generator(int **a,int N,int M)
{
int i,j,m;
srand(time(NULL));
for (i=0; i<N; i++)
for (j=0; j<M; j++){
m = 0 + rand() % 100;
a[i][j]=m;
}
return 0;
}
bool LocalMinimum(int **a, int x, int y, int maxX, int maxY)
{
int i,j,l=0,value=a[x][y];
if (x==0||y==0||x==maxX-1||y==maxY-1) {return false;}
for (i=x-1; i<x+2; i++)
for (j=y-1; j<y+2; j++)
if (value>=a[i][j]){l++;}
l--;
if (l>0) {return false;} else return true;
}
void find(int **a, int maxX, int maxY)
{
int count=0,o[maxX*maxY],i=0,max=0;
for(int x=0;x<maxX;x++)
for(int y=0;y<maxY;y++)
if(LocalMinimum(a, x, y, maxX, maxY))
{
o[i]=a[x][y];
i++;
cout<<"Локальный минимум "<<a[x][y]<<" -> ("<<x+1<<","<<y+1<<")"<<endl;
count++;
}
cout<<"Количество локальных минимумов "<<count<<endl;
count++;
if (i>1){
if (max<o[0]){max=o[0];}
for (int j=0;j<i-1;j++)
if (max<o[j+1])
max=o[j+1];
cout<<"Максимум из локальных минимумов "<<max<<endl<<endl;}
else if (i==1){
cout<<"Максимум из локальных минимумов "<<o[0]<<endl;}
else cout<<"Максимум из локальных минимумов 0"<<endl<<endl;
}
Файл test.cc
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <unistd.h>
#include <fcntl.h>
#include "function.h"
using namespace std;
int main()
{
int i,M,N,**g,**p,**k;
char ch;
FILE *in;
cout<<"1-Инициализировать матрицу с помощью генератора случайных чисел"<<"\n";
cout<<"2-Инициализировать матрицу с помощью пользовательского ввода"<<"\n";
cout<<"3-Заполнить матрицу из файла"<<"\n";
cout<<"0-Выход"<<"\n";
cout<<"Ваш выбор: "<<"\n";
do {
ch = getchar();
switch(ch)
{
case '1' :
cout<<"Введите размер матрицы"<<"\n";
cout<<"Количество строк:";
cin>>N;
cout<<"Количество столбцов:";
cin>>M;
cout<<endl;
g=new int *[N];
for (i=0; i<N; i++)
g[i]=new int [M];
generator(g,N,M);
print(g,N,M);
find(g, N, M);
file(g,N,M);
delete g;
break;
case '2' :
cout<<"Введите размер матрицы"<<"\n";
cout<<"Количество строк:";
cin>>N;
cout<<"Количество столбцов:";
cin>>M;
cout<<endl;
p=new int *[N];
for (i=0; i<N; i++)
p[i]=new int [M];
polz(p,N,M);
print(p,N,M);
find(p, N, M) ;
file(p,N,M);
delete p;
break;
case '3' :
int fflags = O_RDONLY;
int fd=open("file.out",fflags);
if (fd < 0)
{
fprintf (stderr, "Не могу открыть файл!\n");
exit (2);
}
read (fd,&N,sizeof(N));
read (fd,&M,sizeof(M));
k=new int *[N];
for (i=0; i<N; i++)
k[i]=new int [M];
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
read (fd,&k[i][j],sizeof(k[i][j]));
}
}
print(k,N,M);
find(k,N,M);
close(fd);
for (int i = 0; i<N; i++)
delete [] k[i];
delete [] k; }
}
while(ch!='0');
return 0;
}
Файл Makefile
test: test.o function.o
g++ test.o function.o -o test
test.o: test.cc function.h
g++ -c test.cc
function.o: function.cc function.h
g++ -c function.cc
ПРИЛОЖЕНИЕ B
Листинг исходного кода программы
Файл functions.h
#ifndef function_H
#define function_H
#define sizec 100
const int size=1;
struct tip{
int integer[size];
double doubled[size];
float floating[size];
char m[sizec];
bool booling[size];};
void zap(tip *obj);
void create();
void vivod();
void delet();
void create1();
void delet1();
void poiskdir();
void info();
void file(tip *obj);
void file1(tip *obj);
#endif
Файл functions.cc
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include "function.h"
using namespace std;
char k[15];
void create()
{
cout<<"Введите имя файла:";
cin.ignore();
cin.get(k,15);
mode_t fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int fd=creat(k,fmode);
if (fd < 0)
{
fprintf (stderr, "Невозможно создать файл!\n");
exit (2);
}
cout<<"Файл создан!"<<endl<<endl;
close (fd);
}
void delet(){
cout<<"Введите имя файла:";
cin.ignore();
cin.get(k,15);
if (unlink(k)<0)
{ cout<<"Не удалось удалить файл!"<<endl;
exit(2);
}
cout<<"Файл удален!"<<endl<<endl;
}
void create1()
{
cout<<"Введите имя каталога:";
cin.ignore();
cin.get(k,15);
mode_t fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
if (mkdir(k,fmode)< 0)
{
fprintf (stderr,"Невозможно создать каталог!\n");
exit (2);
}
cout<<"Каталог создан!"<<endl<<endl;
}
void delet1(){
cout<<"Введите имя каталога:";
cin.ignore();
cin.get(k,15);
if (rmdir(k)< 0)
{ cout<<"Не удалось удалить каталог!"<<endl;
exit(2);
}
cout<<"Каталог удален"<<endl<<endl;
}
void poiskdir()
{
cout<<"Введите имя каталога:";
cin.ignore();
cin.get(k,15);
DIR *dp;
struct dirent *dent;
dp = opendir(k);
if (!dp){
perror("Ошибка!");
exit(1);
};
while((dent=readdir(dp)) != NULL )
printf("%s [%d] %d\n",dent->d_name,dent->d_type,dent->d_reclen);
closedir(dp);
}
void info()
{
int ret;
struct stat buf;
cout<<"Введите имя файла:";
cin.ignore();
cin.get(k,15);
if ((ret=stat(k,&buf))!=0)
{
fprintf(stderr, "Ошибка! %d", ret);
exit(1);
}
printf("Mode:%d\n", buf.st_mode);
printf("Size:%ld\n", buf.st_size);
printf("Ino:%ld\n", buf.st_ino);
printf("Gid:%d\n", buf.st_gid);
printf("Time last accessed:%ld\n", buf.st_atime);
}
void zap(tip *obj)
{
cout<<"Int:";cin>>obj->integer[0];
cout<<"Double:";cin>>obj->doubled[0];
cout<<"Float:";cin>>obj->floating[0];
cout<<"Char:";
cin.ignore();
cin.getline(obj->m,100);
cout<<"Bool:";cin>>obj->booling[0];
}
void file(tip *obj)
{
cout<<"Введите имя файла:";
cin.ignore();
cin.get(k,15);
int fd=open(k,O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd < 0)
{
fprintf (stderr, "Не могу открыть файл!\n");
exit (2);
}
write(fd,obj->integer,sizeof(obj->integer));
write(fd,obj->doubled,sizeof(obj->doubled));
write(fd,obj->floating,sizeof(obj->floating));
write(fd,obj->m,sizec);
write(fd,obj->booling,sizeof(obj->booling));
close(fd);
}
void file1(tip *obj)
{
cout<<"Введите имя файла:";
cin.ignore();
cin.get(k,15);
mode_t fmode =S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int fflags = O_RDONLY;
int fd=open(k,fflags,fmode);
if (fd < 0)
{
fprintf (stderr, "Не могу открыть файл!\n");
exit (2);
}
read(fd,obj->integer,sizeof(obj->integer));
read(fd,obj->doubled,sizeof(obj->doubled));
read(fd,obj->floating,sizeof(obj->floating));
read(fd,obj->m,sizec);
read(fd,obj->booling,sizeof(obj->booling));
cout<<"Int:";cout<<obj->integer[0]<<endl;
cout<<"Double:";cout<<obj->doubled[0]<<endl;
cout<<"Float:";cout<<obj->floating[0]<<endl;
cout<<"Char:";cout<<obj->m<<endl;
cout<<"Bool:";cout<<obj->booling[0]<<endl;
close(fd);
}
void vivod()
{
cout<<"1-Создать файл"<<"\n";
cout<<"2-Удалить файл"<<"\n";
cout<<"3-Создать каталог"<<"\n";
cout<<"4-Удалить каталог"<<"\n";
cout<<"5-Чтение каталога"<<"\n";
cout<<"6-Получение информации о файле"<<"\n";
cout<<"7-Запись в файл информации"<<"\n";
cout<<"8-Вывести информацию из файла"<<"\n";
cout<<"0-Выход"<<"\n";
cout<<"Ваш выбор: "<<"\n";
}
Файл test.cc
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "function.h"
using namespace std;
tip *obj = new tip;
int main()
{
char ch;
vivod();
do {
ch = getchar();
switch(ch)
{
case '1' : create();vivod();break;
case '2' : delet();vivod();break;
case '3' : create1();vivod();break;
case '4' : delet1();vivod();break;
case '5' : poiskdir();vivod();break;
case '6' : info();vivod();break;
case '7' : zap(obj);file(obj);vivod();break;
case '8' : file1(obj);vivod();break;
}
}
while(ch!='0');
return 0;
}
Файл Makefile
test: test.o function.o
g++ test.o function.o -o test
test.o: test.cc function.h
g++ -c test.cc
function.o: function.cc function.h
g++ -c function.cc
ПРИЛОЖЕНИЕ С
Листинг исходного кода программы
function.h
#ifndef function_H
#define function_H
void delet(char k[15]);
void vivod();
void file(char k[15]);
#endif
function.cc
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include "function.h"
#define bufsize 2500
using namespace std;
char buf[bufsize];
char t[bufsize];
void delet(char k[15])
{
int i;
int x=bufsize,x1=bufsize;
mode_t fmode =S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int fflags = O_RDONLY;
int fd=open(k,fflags,fmode);
if (fd < 0)
{
fprintf (stderr, "Не могу открыть файл!\n");
exit (2);
}
read(fd,buf,bufsize);
for(i=0;i<x1;i++)
if(buf[i]=='\t')
{
for(int j=i;j<x1;j++)
buf[j]=buf[j+1];
x1--;
i--;
}
for(i=0;i<x;i++)
if(buf[i]==' ')
if(buf[i+1]==' ')
{
for(int j=i;j<x;j++)
buf[j]=buf[j+1];
x--;
i--;
}
cout<<buf;
close(fd);
}
void file(char k[15])
{
mode_t fmode =S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int fflags = O_WRONLY | O_TRUNC;
int fd1=open(k,fflags,fmode);
cout<<buf;
if (fd1 < 0)
{
fprintf (stderr, "Не могу открыть файл!\n");
exit (2);
}
write(fd1,buf,strlen(buf));
close(fd1);
}
void vivod()
{
cout<<"1-Удалить пробелы и табуляции"<<"\n";
cout<<"0-Выход"<<"\n";
cout<<"Ваш выбор: "<<"\n";
}
test.cc
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "function.h"
using namespace std;
int main()
{
char ch;
char k[15];
vivod();
do {
ch = getchar();
switch(ch)
{
case '1' :
cout<<"Введите имя файла:";
cin.ignore();
cin.get(k,15);
delet(k);file(k);vivod();break;
}
}
while(ch!='0');
return 0;
}