Пожалуйста, поделитесь опытом, как это делать? Вопрос насущный. Даже для маленьких временных файлов создаваемых через Files.dir.New(), как я понял, идет обращение к диску. А очень бы хотелось, как вы говорите "над памятью".
Никакого секрета тут нет: как реализуете
абстракцию, так "она" и будет работать.
1) Ограниченная реализация файлов в памяти, насколько помню, есть в подсистеме Dbu (
http://www.zinnamturm.eu/downloadsDH.htm#Dbu)
2) Простейший пример:
http://oberoncore.ru/library/temir_srav ... _ble_kboksКод:
MODULE PrivFixedMemFiles;
(*
File
Reader
Writer
*)
IMPORT Files;
TYPE
File* = POINTER TO RECORD (Files.File)
len-: INTEGER;
data-: ARRAY 4096 OF BYTE
END;
Reader* = POINTER TO RECORD (Files.Reader)
base: File;
pos: INTEGER
END;
Writer* = POINTER TO RECORD (Files.Writer)
base: File;
pos: INTEGER
END;
(* File *)
PROCEDURE (f: File) Close*;
BEGIN
HALT(100)
END Close;
PROCEDURE (f: File) Flush*;
BEGIN
HALT(100)
END Flush;
PROCEDURE (f: File) Length* (): INTEGER;
BEGIN
RETURN f.len
END Length;
PROCEDURE (f: File) NewReader* (old: Files.Reader): Files.Reader;
VAR res: Reader;
BEGIN
IF (old # NIL) & (old IS Reader) THEN res := old(Reader) ELSE NEW(res) END;
IF res.base # f THEN
res.base := f; res.SetPos(0)
END;
res.eof := FALSE;
RETURN res
END NewReader;
PROCEDURE (f: File) NewWriter* (old: Files.Writer): Files.Writer;
VAR res: Writer;
BEGIN
IF (old # NIL) & (old IS Writer) THEN res := old(Writer) ELSE NEW(res) END;
IF res.base # f THEN
res.base := f; res.SetPos(f.len)
END;
RETURN res
END NewWriter;
PROCEDURE (f: File) Register* (name: Files.Name; type: Files.Type; ask: BOOLEAN; OUT res: INTEGER);
BEGIN
HALT(100)
END Register;
(* Reader *)
PROCEDURE (r: Reader) Base* (): Files.File;
BEGIN
RETURN r.base
END Base;
PROCEDURE (r: Reader) Pos* (): INTEGER;
BEGIN
RETURN r.pos
END Pos;
PROCEDURE (r: Reader) SetPos* (pos: INTEGER);
BEGIN
ASSERT(0 <= pos, 20); ASSERT(pos <= r.base.len, 21);
r.pos := pos;
r.eof := FALSE
END SetPos;
PROCEDURE (r: Reader) ReadByte* (OUT x: BYTE);
VAR f: File;
BEGIN
f := r.base;
IF r.pos < f.len THEN
x := f.data[r.pos];
INC(r.pos);
r.eof := FALSE
ELSE
x := 0;
r.eof := TRUE
END
END ReadByte;
PROCEDURE (r: Reader) ReadBytes* (VAR x: ARRAY OF BYTE; beg, len: INTEGER);
VAR f: File; i, j: INTEGER;
BEGIN
ASSERT(0 <= beg, 20); ASSERT(0 <= len, 21); ASSERT(beg + len <= LEN(x), 22);
f := r.base;
i := beg; j := r.pos;
WHILE (j < f.len) & (len > 0) DO
x[i] := f.data[j];
INC(i); INC(j);
DEC(len)
END;
r.eof := len > 0;
r.pos := j
END ReadBytes;
(* Writer *)
PROCEDURE (w: Writer) Base* (): Files.File;
BEGIN
RETURN w.base
END Base;
PROCEDURE (w: Writer) Pos* (): INTEGER;
BEGIN
RETURN w.pos
END Pos;
PROCEDURE (w: Writer) SetPos* (pos: INTEGER);
BEGIN
ASSERT(0 <= pos, 20); ASSERT(pos <= w.base.len, 21);
w.pos := pos;
END SetPos;
PROCEDURE (w: Writer) WriteByte* (x: BYTE);
VAR f: File;
BEGIN
f := w.base;
ASSERT(f.len + 1 <= LEN(f.data), 100);
f.data[w.pos] := x;
INC(w.pos);
IF w.pos > f.len THEN f.len := w.pos END
END WriteByte;
PROCEDURE (w: Writer) WriteBytes* (IN x: ARRAY OF BYTE; beg, len: INTEGER);
VAR f: File; i: INTEGER;
BEGIN
ASSERT(0 <= beg, 20); ASSERT(0 <= len, 21); ASSERT(beg + len <= LEN(x), 22);
f := w.base;
ASSERT(f.len + len <= LEN(f.data), 100);
i := beg;
WHILE len > 0 DO
f.data[w.pos] := x[i];
INC(w.pos); INC(i);
DEC(len)
END;
IF w.pos > f.len THEN f.len := w.pos END
END WriteBytes;
(* Программный интерфейс *)
PROCEDURE New* (): File;
VAR res: File;
BEGIN
NEW(res);
res.len := 0;
RETURN res
END New;
END PrivFixedMemFiles.