Рефераты Ідея буферизації

Вернуться в Кибернетика

Ідея буферизації
. Отже, файл f записів типу Student можна відкрити викликом

ReSet(f, SizeOf(Student)).

Після цього виклик вигляду

BlockRead(f, Buf, n, nreal)

задає читання n блоків по 48 байтів у пам’ ять змінної Buf.

Головну роль у швидкості читання безтипових файлів відіграє розмір "внутрішнього буфера". Чим він більше, тим менше звернень до зовнішнього носія і швидше обробка файла. Але все добре в міру.

Можете перевірити твердження, що за розмірів буфера, кратних 512 байтам і більших 8K байтів, швидкість читання файлів практично стала.

Процедура блочного виведення BLOCKWRITE також має 4 аналогічні параметри. Відмінність її в тім, що дані з "внутрішнього буфера" через блок записуються в кінець файла. Зрозуміло, спочатку для файла треба установити розмір "зовнішнього" буфера викликом вигляду ReWrite(f, m).

Повернемося до задачі копіювання й напишемо програму, виконання якої в сотні (!) разів швидше від програми StupidCopy. У ролі "внутрішнього буфера" виступає масив символів Buf розміром у Bufsz=32K байтів. Спочатку за викликом FileSize визначається розмір вхідного файла в байтах, а потім файл читається в масив порціями по Bufsz байтів. Обробка цього буфера в даному разі полягає в блочному копіюванні у вихідний файл. Остання порція може містити менше, ніж Bufsz байтів – масив заповнюється та переписується в файл не до кінця.

program QuickCop;

const Bufsz=32768;

var f, g : file;

Buf : array[1..Bufsz] of char;

restfil, portion : Longint;

rdin, wrou : word; s : string;

begin

writeln( 'Задайте ім'я файла-джерела:');

readln (s); assign (f , s );

writeln( 'Задайте ім'я цільового файла:');

readln (s); assign (g , s );

reset(f, 1); rewrite(g, 1);

restfil:=filesize(f);

while restfil>0 do

begin

if restfil>Bufsz then portion:=Bufsz

else portion:=restfil;

dec(restfil, portion);

Blockread (f, Buf, portion, rdin);

if rdin<>portion then

begin

writeln('Помилка читання файла'); halt

end;

Blockwrite(g, Buf, portion, wrou);

if wrou<>portion then

begin

writeln('Помилка запису файла'); halt

end;

end;

close(g); close(f);

end.

Два зауваження щодо цієї програми. По-перше, до неї можна додати обчислення часу, який займає обробка файла. Для цього слід задати на початку програми підключення модуля Dos і скористатися його процедурою GETTIME. Слід означити 4 змінні типу Word, наприклад,

th, tm, ts, tms : word.

Можна записати виклик

Gettime(th, tm, ts, tms)

десь на початку тіла програми, наприклад, перед відкриванням файлів. За його виконання змінним присвоюються відповідно години, хвилини, секунди ті мілісекунди від вбудованого в комп’ ютер годинника.

Обробка значень цих змінних залежить від смаків програміста. Наприклад, за ними можна обчислити час у сотих долях секунди. Означимо змінну tim типу longint:

tim:=((th*60+tm)*60+ts)*100+tms div 10;

Наприкінці програми запишемо

gettime(th, tm, ts, tms);

tim:=((th*60 + tm)*60 + ts)*100 + tms div 10 - tim;

writeln('Витрачено часу : ', (tim div 100):1, '.',

(tim mod 100 div 10):1,

(tim mod 100 mod 10):1, ' sec'

)

Тоді друкується час виконання у секундах на зразок 3.62 чи 0.01.

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

QuickCop file.in file.out

то рядок 'file.in' є значенням, що повертається з виклику ParamStr(1), 'file

Добавить в Одноклассники    

 

Rambler's Top100