Създаване на допълнително дисково пространство с Delphi
Относно файловете и паметта
Мнозина не знаят (аз самият не знаех, докато не ми казаха) за една възможност при писане на програми. Очевидно е, но докато не възникне нужда, никой не мисли за това. Имам предвид работа във файл "без тип". Основното е, че ние записваме нашите обемни данни точно в този файл на винта, а не в RAM. Ако трябва да промените някоя част, прочетете в паметта, променете и запишете обратно. Ние създаваме, така да се каже, нашата лична малка RAM памет. Photoshop, например, прави това. Но тази технология е оправдано да се използва само ако нямате достатъчно RAM, тъй като твърдият диск е многократно по-бавен от RAM. Да, и програмирането става по-трудно, защото в случая с RAM не ни интересува разпределението / освобождаването на динамична памет - GetMem, FreeMem и това е. В случай на файл, ще трябва сами да напишем тези процедури, да създадем списък с дупки (свободни области във файла), процедури за обслужване на този списък. Да се създадат като цяло механизми за управление на паметта, които вече са внедрени в ОС.
Нека обясня с пример.
За да напишем стойността на променлива във файл, нямаме нужда от нищо друго освен тази променлива, защото нейният размер може да бъде намерен с помощта на функцията SizeOf. Например, ако a: цяло число, f: файл, тогава BlockWrite(f, a, SizeOf(a)). За да запишете някакъв обект в паметта, трябва да имате указател към този обект и неговия размер:
p: показалец;
размер: цяло число;
BlockWrite(f, p^, size)
Променливата a може също да бъде записана с помощта на указател към нея:
p := @a;
размер := SizeOf(a);
BlockWrite(f, p^, size)
Трябваше да напиша универсална процедура за запис на обекти във файл (под думата обект IНямам предвид обекта, който е в основата на ООП, а просто някаква нотация, например, както е декларирано по-долу):
тип
TSomeType = запис
ключ, размер: цяло число; //уникално ключово поле и размер
//други полета
x: масив [1..8] от байт
край;
променлива b: TSomeType
Сега ще покажа как можете да прочетете вторите четири байта, ако показалецът сочи към първия. Нека кажем и това:
тип
TArray12 = масив[1..2] от цяло число;
променлива
m: TArray12;
Окачете го някъде в ButtonClick, за да видите дали работи.
//попълнете полетата за ключ и размер
b.key := 512;
b.size := 1024;
//формирайте указател към този запис
p := @b;
//прочетете първите осем байта в масива
m := TArray12(p^);
// и показване на втория елемент от масива — размера на полето
ShowMessage(IntToStr(m[2]));
Вариант 1. Asm
Нека имаме променлива указател
p: показалец
Малък примерен код, с който можете да правите каквото искате с този показалец:
asm
бутнете eax
//запазете eax за всеки случай
mov eax, p
//поставяме стойността на нашия указател в eax
//и направете нещо с него, например увеличете с 4
добавете eax, 4
mov p,eax
//запишете новата стойност на указателя обратно в паметта
//и възстановете eax
поп eax
край; //asm
Всичко е просто! Сега, вместо да добавяте, заменете това, от което се нуждаете - и го използвайте за ваше здраве! Ще дам друг пример за добавяне на два указателя p1 и p2 втрети p:
asm
бутнете eax
натиснете ebx
//запазване на променливи регистри
mov eax, p1
mov ebx, p2
//поставете в регистрите стойностите на условията на указателите
добавете eax, ebx
//добавяне и запис в третия указател
mov p,eax
поп ebx
поп eax
//възстановени регистри
край; //asm
Вариант 2. Без асма
За да направим това, имаме нужда от още няколко променливи - a: LongInt (4 байта, цяло число, без знак) и указател към променливи от тип LongInt: pInt: ^LongInt.
пинта := @p;
a := пинта^;
//прочетете тази стойност
a := a + 4;
//променено
pInt^ := a;
//и ми отговори
Дори излезе цял ред по-къс!