Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
8
Добавлен:
19.02.2016
Размер:
69.12 Кб
Скачать

Міністерство освіти, науки, молоді та спорту України

Житомирський державний технологічний університет

ФІКТ

Кафедра ПЗОТ

Група ПІК-9

Лабораторна робота №1

Програми копіювання файлів

Виконав : Оленюк О.О.

Перевірив : Власенко О.В.

Житомир

2012 р.

Завдання:

  1. Навчитися користуватись програмами copy1.exe та copy2.exe.

  2. Розібрати роботу програм.

  3. В програмі copy1.c замінити бінарний режим доступу до обох файлів на текстовий і запустити програму для копіювання досить великого бінарного файлу. Результати експерименту зафіксувати в зошиті. Пояснити причину ефекту.

  4. В програмі copy1.c замінити бінарний режим доступу до файлу, який записується, на текстовий і запустити програму. Результати експерименту зафіксувати в зошиті. Пояснити причину ефекту.

  5. В програмі copy2.c знайти оптимальний розмір буферу. Обгрунтувати вибір.

  6. В програмі copy2.c модифікувати програму так, щоб вона виводила на екран вміст файлу за допомогою функцій puts(), fputs, printf(), fwrite().Результати експерименту зафіксувати в зошиті. Пояснити причину ефекту.

Виконання роботи

    1. Розбираємо програму copy1.c

#include <io.h>

#include <conio.h>

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <sys\types.h>

#include <sys\stat.h>

#include <alloc.h>

#include <errno.h> // Підключення бібліотек

#define BUFSIZE 10000 // Оголошення константи

void main( int argc, char **argv ) { // Доступ до командної строчки

int source, target;

int i;

char *buffer; // Оголошення змінних

int count;

if( argc != 3 ) {

printf( "\n" "Usage: COPY1 [d:][\\path]source_file [d:][\\path]target_file \n" );

exit( 1 );

} // В разі невідповідності кількості констант виводиться повідомлення про правильність написання.

if( ( source = open( argv[ 1 ], O_BINARY | O_RDONLY ) ) == -1 ) {

printf( "\n Open source file error: %d", errno );

exit( 2 );

} // Відбувається відкриття нашого початкового файлу, бінарний доступ, тільки читання.

target = open( argv[ 2 ], O_BINARY | O_WRONLY | O_CREAT | O_EXCL,

S_IREAD | S_IWRITE );

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

if( errno == EEXIST ) {

printf( "\n File already exists. Overwrite? (Y/N) \n" );

i = getch();

if( ( i == 'y' ) || ( i == 'Y' ) )

target = open( argv[ 2 ], O_BINARY | O_WRONLY | O_CREAT | O_TRUNC,

S_IREAD | S_IWRITE );

} // В разі виникнення помилки типу Файл уже існує вивводиться повідомлення, при необхідності перезапису, файл створюється знову з відсіканням попереднього змісту

if( target == -1 ) {

printf( "\n Open target file error: %d", errno );

exit( 2 );

} // Відбувається спроба відкрити кінцевий файлу, в разі неможливості виводиться помилка

count = BUFSIZE;

if( ( buffer = ( char* )malloc( count ) ) == NULL ) {

printf( "\n Not enough memory" );

exit( 3 );

} // Перевіряється наявність вільної пам’яті на диску, в разі її відсутності – виводиться помилка

while( !eof( source ) ) {

if( ( count = read( source, buffer, count ) ) == -1 ) {

printf( "\n Read file error: %d", errno );

exit( 4 );

}

// Відбувається читання початкового файлу,

if( ( count = write( target, buffer, count ) ) == -1 ) {

printf( "\n Write file error: %d", errno );

exit( 5 );

}

// Відбувається запис в кінцевий файл

}

close( source );

close( target );

free( buffer );

} // Закриття обох файлів, вивільнення буферу

    1. Розбираємо програму COPY2.C

#include <stdio.h>

#include <stdlib.h>

#include <time.h> // Підключення бібліотек

void filecpy( FILE *stream_from, FILE *stream_to ); // Доступ до командної строчки

char buf1[ BUFSIZ * 10 ];

char buf2[ BUFSIZ * 10 ]; ; // Оголошення змінних

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

time_t start, end;

FILE *stream_from, *stream_to;

if( argc < 3 ) {

printf( "\nUsage:"

" COPY2 [d:][\\path]source_file [d:][\\path]target_file\n" );

exit( 1 );

}

// В разі невідповідності кількості констант виводиться повідомлення про правильність написання.

// Проводимо копіювання файлу з буфером стандартного розміру (512 b)

if( ( stream_from = fopen( argv[ 1 ], "rt" ) ) == NULL ) {

printf( "\nOpen source file error: %d", errno );

exit( 1 );

}

// Відкриваємо файл для читання в текстовому режимі та копіюємо його за допомогою буферу стандартного розміру

stream_to = fopen( argv[ 2 ], "wt+" );

// Відкриваємо другий файл для запису в текстовому режимі

start = clock(); // Визначаємо час початку копіювання

filecpy( stream_from, stream_to ); // За допомогою спеціальної функції проводимо копіювання

end = clock(); // Визначаємо час закінчення копіювання

printf( "Copying time is %5.1f. Buffer size is %d bytes\n",

( ( float )end - start ) / CLK_TCK, BUFSIZ ); // Виводимо результат

// Проводимо копіювання файлу з буфером більшого розміру (5120 b)

if( ( stream_from = fopen( argv[ 1 ], "rt") ) == NULL )

exit( 1 );

stream_to = fopen( argv[ 2 ], "wt+" );

setvbuf( stream_from, buf1, _IOFBF, sizeof( buf1 ) ); // Визначаємо розмір буферу для першого файлу

setvbuf( stream_to, buf2, _IOFBF, sizeof( buf2 ) ); // Визначаємо розмір буферу для другого файлу

start = clock();

filecpy( stream_from, stream_to );

end = clock();

printf( "Copying time is %5.1f. Buffer size is %d bytes\n",

( ( float )end - start ) / CLK_TCK, BUFSIZ * 10 );

// Проводимо копіювання файлу без використання буферизації

if( ( stream_from = fopen( argv[ 1 ], "rt") ) == NULL )

exit( 1 );

stream_to = fopen( argv[ 2 ], "wt+" );

setvbuf( stream_from, NULL, _IONBF, 0 ); // Визначаємо нульовий розмір буферу

setvbuf( stream_to, NULL, _IONBF, 0 ); // Визначаємо нульовий розмір буферу

start = clock();

filecpy( stream_from, stream_to );

end = clock();

printf( "Copying time is %5.1f. Buffers is not used\n",

( ( float )end - start ) / CLK_TCK );

exit( 0 );

}

/****************************************************************************

* filecpy - функция копирования файлов с использованием потоков ввода/вывода

* Args: stream_from - поток, откуда копировать;

* stream_to - поток, куда копировать;

* Return: none.

* Globals:none.

****************************************************************************/

// Задаємо параметри нашої функції filecpy

void filecpy( FILE *stream_from, FILE *stream_to ) {

char linebuf[ 256 ];

while( !feof( stream_from ) ) {

if( fgets( linebuf, 255, stream_from ) == NULL ) break;

if( fputs( linebuf, stream_to ) == EOF ) break;

}

fclose( stream_from );

fclose( stream_to );

}

3. В програмі copy1.c при заміні бінарного режиму доступу до обох файлів на текстовий і запустивши програму отримуємо дуже маленький вихідний файл який не відповідає початковому. Це викликано тим, що в текстовому режимі доступу, як тільки з файлу зчитується символ Ctrl-Z (ASCII 1Ah), вважається, що досягнуто кінець файлу (умова EOF). І подальший запис припиняеться, що і відбулося в нашому випадку.

4. В програмі copy1.c при заміні бінарного режим доступу до файлу, який записується, на текстовий і запустивши программу отримуємо файл, по розміру майже схожий з нашим початковим, але відкриття якого неможливе. Це викликано тим, що початковий файл був відкритий за допомогою бінарного доступу, а кінцевий в текстовому режимі, саме через цю розбіжність у кінцевому файлі не відбулася обернена трансляція символів.

5. Запустивши програму copy2.c для копіювання файлу досить великого розміру (5 Мb) отримуємо такі вихідні результати програми:

Copying time is 0.7. Buffer size is 512 bytes

Copying time is 0.5. Buffer size is 5120 bytes

Copying time is 14.5. Buffers is not used

З побаченого можна зробити висновок, що в даних випадках оптимальний розмір буферу являє собою 512 біт. Тому що в порівнянні з буфером в 5120 біт, різниця в часі між ними лише в 0.2 секунди, що є досить малою, з врахуванням того що буфер в 5120 біт в десять разів більшим. Ну а не використання буферизації взагалі призводить до значних затрат часу.

6. В програмі copy2.c модифікуємо програму так, щоб вона виводила на екран вміст файлу за допомогою функцій puts(), fputs, printf(), fwrite(). В результаті наші функції матимуть вигляд:

puts(buf1); // Функція виводить вміст буферу (buf1) на стандартний пристрій виведення, а саме на монітор.

fputs(buf1,stdout); // Функція виводить вміст буферу (buf1) в параметр stdout, що являє собою монітор.

printf("Sodergimoe fayla:\n %s", buf1); // стандартна функція виведення значення змінної buf1.

fwrite(buf1, sizeof(buf1), 1, stdout); // Копіює вміст buf1, коміркою розміром buf1, один раз, на монітор.

//Доступ до файлів на низькому рівні – через дескриптори (описувач), на високому – через потоки.

Дискриптор – це число, яке задає номер певного ресурсу (блок пам'яті, файл, курсор, шрифт…) під час роботи з ним.

Чому не відбувається копіювання двійкових файлів через символьний режим.

Соседние файлы в папке СПЗ отчеты (Власенко О.В.)