Необходимо динамический массив типа array of array of array of integer сохранить в файл, и потом прочитать его в переменную такого же типа. Что можно сделать? Есть стандартные решения из библиотек?
Спасибо
Необходимо динамический массив типа array of array of array of integer сохранить в файл, и потом прочитать его в переменную такого же типа. Что можно сделать? Есть стандартные решения из библиотек?
Спасибо
Ну, BinaryWriter/BinaryReader
begin
var ms := new System.IO.MemoryStream(1000);
var bw := new System.IO.BinaryWriter(ms);
var a: array of array of array of integer := |||1,2,3|,|4,5,6||,||7,8,9|,|10,11,12|||;
bw.Write(a.Length);
for var i := 0 to a.Length - 1 do
begin
bw.Write(a[i].Length);
for var j := 0 to a[i].Length - 1 do
begin
bw.Write(a[i, j].Length);
for var k := 0 to a[i, j].Length - 1 do
begin
bw.Write(a[i, j, k]);
end;
end;
end;
System.IO.File.WriteAllBytes('array.dat', ms.ToArray());
ms := new System.IO.MemoryStream(System.IO.File.ReadAllBytes('array.dat'));
var br := new System.IO.BinaryReader(ms);
var a2: array of array of array of integer;
var len := br.ReadInt32();
SetLength(a2, len);
for var i := 0 to a2.Length - 1 do
begin
len := br.ReadInt32();
SetLength(a2[i], len);
for var j := 0 to a2[i].Length - 1 do
begin
len := br.ReadInt32();
SetLength(a2[i, j], len);
for var k := 0 to a2[i, j].Length - 1 do
begin
a2[i, j, k] := br.ReadInt32();
end;
end;
end;
end.
С подпрограммами чище даже когда размер кода это не уменьшает:
## uses System.IO;
procedure WriteArr<T>(self: BinaryWriter; a: array of T; write_item: (BinaryWriter,T)->()); extensionmethod;
begin
self.Write(a.Length);
foreach var x in a do
write_item(self, x);
end;
function ReadArr<T>(self: BinaryReader; read_item: BinaryReader->T): array of T; extensionmethod :=
ArrGen(self.ReadInt32, i->read_item(self));
var a := |||1,2,3|,|4,5,6||,||7,8,9|,|10,11,12|||;
var fname := 'a.bin';
begin
var f := &File.Create(fname);
BinaryWriter.Create(f)
.WriteArr(a, (bw,a)->
begin
bw.WriteArr(a, (bw,a)->
begin
bw.WriteArr(a, (bw,x)->
bw.Write(x)
)
end)
end);
f.Close;
end;
begin
var f := &File.OpenRead(fname);
Println(
BinaryReader.Create(f)
.ReadArr(br->br
.ReadArr(br->br
.ReadArr(br->br
.ReadInt32
)
)
)
);
f.Close;
end;
Вы, кстати, уверены что вам нужно именно array of array of array of integer
(массив массивов массивов) а не array[,,] of integer
(3-х мерный массив)? Такая вложенность редко бывает оправдана…
Спасибо за исчерпывающий ответ. Неожиданно получить ответ в готовом виде. Специально писали?
Спасибо за важное дополнение
Да, уверен, это оправдано. В массиве [, ,] будет избыточность объема перед вложенностью, где каждый индекс содержит уже обработанную информацию.
Довольно часто избыточность хранения данных - невысокая плата за удобство работы с ними.
В таком случае обычно стоит объявить свои типы данных для каждого уровня вложенности массива и инкапсулировать работу с ними.
Вы имеете в виду для читабельности? Или какие то другие соображения?
И для масштабируемости
Да, Вы правы. Но я на пределе оперативки. Приходится хранить только нужную информацию.
Соображения те же, по которым я изменил код от ibond-а, добавив подпрограммы.
Масштабируемость и читабельность это только некоторые из плюсов. Но в общем случае - разбиение сложной структуры данных на несколько простых увеличивает модульность кода.
Кроме тех 2 плюсов, к примеру, после разбиения на:
SmallThing = record
a: array of integer;
end;
MediumThing = record
a: array of SmallThing;
end;
LargeThing = record
a: array of MediumThing;
end;
И объявления конструктора и методов в этих типах - вы можете очень легко использовать MediumThing
напрямую, если окажется что где то надо на 1 уровень вложенности меньше. Или наоборот, если надо на 1 уровень больше - не надо делать дубли кода или ещё сильнее усложнять обрабатывающий код.
Согласен, так удобнее. Кроме, возможно, одного нюанса, если нужно узнать структуру LargeThing, придется отматывать назад к MediumThing, а потом к SmallThing.
Это работает!
Спасибо Вам.
У меня этой проблемы ни разу не возникало с тех пор, как я поставил на компьютер 64 Гб оперативки.
Пока не возникла необходимость найти результат попарных комбинаций двух массивов по 10.000.000 ячеек
Я только сейчас увидел, что мне отвечает автор учебника по PABC. Ваша книга постоянно открыта. Я по ней учусь. Стараюсь соответствовать в меру способностей.
С уважением
Это не учебник, скорее справочник, причем по достаточно старой версии 3.5. Но достаточно глубокий. Менее глубоки, но зато постоянно актуальны сведения из этого учебного курса