powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как сохранить в файл запись (record) с динамическими массивами?
25 сообщений из 45, страница 1 из 2
Как сохранить в файл запись (record) с динамическими массивами?
    #39742643
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как сохранить в файл запись (record) с динамическими массивами?
file of, естественно, не работает.
Вручную сохранять по одной переменной - не хочется.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742654
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

Покажи, что именно ты имеешь ввиду под "запись (record) с динамическими".
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742661
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: pascal
1.
2.
3.
4.
5.
6.
procedure SaveArray(Stream: TStream; const iArr: TDynArray);
var
  aLen: Integer;
begin
  aLen := Length(iArr);
  Stream.WriteBuffer(Pointer(iArr)^, aLen * SizeOf(Integer));
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742662
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

в общем виде только серелиализацию писать, например с помощью TypInfo
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742674
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered> file of, естественно, не работает.

Покажи код.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742716
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да любую, хотя бы, такую.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
type trec=record
  a:integer;
  c:array of integer;
  b:double;
  end;

var rec:array of trec;
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742730
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может, JSON?
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742797
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

Так тебе запись с динамическими массивами или массив записей с массивами?
В первом случае можно в бинарном виде без цикла за три последовательных акта записи,
во втором в общем случае без цикла, имхо, не обойтись.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742803
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Массив записей с массивами.
Тут ещё придумал, что можно с помощью Move скопировать всё содержимое записи, за исключением указателей. А вот как бы ещё динамический массив скопировать, тоже напрямую из памяти, вместе с длиной? И потом загрузить из файла таким же образом.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742868
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

См. выше про три порции. Первый move() это собственно сам record. Потом пишешь длину массива и затем опять через move() содержимое динмассива. Читаешь в том же порядке, только перед третьим чтением делаешь массиву нужный (прочитанный вторым чтением) SetLenth().
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742878
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Динамический массив же не копируется через Move, копируется только указатель.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39742880
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

А мужики-то и не знают.)))
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743081
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну так пусть мужики пример приведут, что-ли, однако.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743089
MBo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBo
Гость
registered, для динамических массивов, элементы которых не содержат, в свою очередь, динамических элементов (в т.ч. строк), можно копировать тело массива так:

Код: pascal
1.
    Move(SrcArr[0], DstArr[0], SizeOf(SrcArr[0])*Length(SrcArr));



Общее правило для использования строк, дин. массивов в качестве нетипизированного var/const параметра - разыменовать указатель (т.к. компилятор сам возьмёт адрес переменной)

Вариант:
Код: pascal
1.
    MemoryStream.ReadBuffer(PChar(AString)^ ...
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743095
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

Начинаю догадываться, - студент? курсовая? А поиск в сети по ключевым словам еще не проходили?
К тебе же третий от начала пост был на эту тему, - спроецируй его самостоятельно на Move().
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743106
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в любом случае нужно еще длину поля динамического массива в record тоже записывать)))
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743108
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registeredНу так пусть мужики пример приведут, что-ли, однако.сначала студент напишет свой вариант кода, вот тогда и будем смотреть, что ты написал и что нужно исправить.

А если студент этого не хочет делать (выкладывать свой вариант), то тогда бегом в режим заказа платной разработки, коль сам не можешь/не хочешь
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743116
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2,

Это только если делать транспортабельный (считываемый другими приложениями) формат.
А в своем собственном длину отдельного элемента и так знает. Другое дело что в рекорд
можно было ввести длину самого динамического массива, тогда писать/читать можно
было бы не за три итерации, а за две.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743118
gssbox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Делал такое использовал RTTI и дженерики, но в конечном счете пришлось отказаться от этой идеи так как тормозило при интенсивных нагрузках.

Вот пример кода:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
type
  TPrmName = array[0..127] of AnsiChar;

type
 TPrmBlock = packed record
   PrmName    : TPrmName;  //Имя параметра
   PrmType    : TTypeKind; //Тип параметра
   TypeSize   : Integer;   //Размер параметра
 end;

procedure TUFF<T1, T2, T3, T4>.ReadOrWriteDataToRecordPrm<T>(Param: Pointer; PrmBlock: TPrmBlock; FS: TFileStream; Mode: Byte);
var
  RType     : TRTTIType;
  Fields    : TArray<TRttiField>;
  I         : Integer;
  P         : Pointer;
  RecValue  : TValue;
  ArrLength : NativeInt;
  TypeSize  : NativeInt;
  B         : TArray<Byte>;
  PrmSize   : Integer;
  S         : String;
  pS        : PString;
  NotFound  : Boolean;
begin

  NotFound := true;
  RType := TRTTIContext.Create.GetType(TypeInfo(T));

  Fields := RType.GetFields;
  for I := 0 to High(Fields) do
   begin
       if Assigned(Fields[I].FieldType) then
        begin
                  if UpperCase(Fields[I].Name) = UpperCase(String(PrmBlock.PrmName)) then {Совпали имена параметров}
                    begin

                     if (Fields[I].FieldType.TypeKind = PrmBlock.PrmType){ and
                        (Fields[I].FieldType.TypeSize = PrmBlock.TypeSize)} then {Совпал тип параметра}
                      begin
                       {Получаем указатель на конкретный параметр из record-a}
                       P := Pointer(Integer(Param) + Fields[I].Offset);

                                       case Mode of
                                            ReadMode  : begin
                                                               case Fields[I].FieldType.TypeKind of
                                                                tkUString : begin {String}
                                                                              {Читаем длину строки}
                                                                              FS.Read(PrmSize, SizeOf(PrmSize));
                                                                              {Загружаем строку во временный массив B, и перекодируем в String}
                                                                              SetLength(B, PrmSize);
                                                                              FS.Read(B[Low(B)], PrmSize);
                                                                              S  := TEncoding.UTF8.GetString(B);
                                                                              pS := P;
                                                                              SetLength(pS^, Length(S));
                                                                              move(Pointer(S)^, PPointer(P)^^, Length(S) * StringElementSize(S));
                                                                            end;

                                                                tkDynArray: begin {Динамические массивы}
                                                                             FS.Read(PrmSize, SizeOf(PrmSize));
                                                                             RecValue  := Fields[I].GetValue(Param);
                                                                             TypeSize  := RecValue.TypeInfo.TypeData^.elSize;
                                                                             ArrLength := PrmSize div TypeSize;
                                                                             {Dimension - размерность массива 1- 1D, 2 - 2D и т.д.}
                                                                             if ArrLength > 1024 * 1024 * 10 then
                                                                              begin
                                                                                UpdateMessage('BigSize: ' + IntToStr(PrmSize) + ' - ' + IntToStr(FS.Position));
                                                                                ArrLength := 0;
                                                                              end;
                                                                             DynArraySetLength(PPointer(P)^, RecValue.TypeInfo, 1{Dimension}, @ArrLength);
                                                                             FS.Read(PPointer(P)^^, ArrLength * TypeSize);
                                                                            end;

                                                                            else
                                                                             FS.Read(P^, Fields[I].FieldType.TypeSize);
                                                                end;
                                                        end;

                                            WriteMode : begin
                                                               case Fields[I].FieldType.TypeKind of

                                                                tkUString : begin {String}
                                                                              {Преобразуем строку в UTF8 и помещаем ее в массив}
                                                                              B := TEncoding.UTF8.GetBytes(PPointer(P)^);
                                                                              {Пишем длину строки}
                                                                              PrmSize := Length(B);
                                                                              FS.Write(PrmSize, SizeOf(PrmSize));
                                                                              {Пишем строку в поток в кодировке UTF8}
                                                                              FS.Write(B[Low(B)], Length(B));
                                                                            end;

                                                                tkDynArray: begin {Динамические массивы}
                                                                             RecValue  := Fields[I].GetValue(Param);
                                                                             ArrLength := RecValue.GetArrayLength;
                                                                             TypeSize  := RecValue.TypeInfo.TypeData^.elSize;
                                                                             PrmSize   := ArrLength * TypeSize;
                                                                             {Пишем размер массива байтах}
                                                                             FS.Write(PrmSize, SizeOf(PrmSize));
                                                                             //PPointer(P)^ - указатель на первый(нулевой) элемент массива
                                                                             {Пишем сам массив}
                                                                             FS.Write(PPointer(P)^^, PrmSize);
                                                                            end;

                                                                            else
                                                                             FS.Write(P^, Fields[I].FieldType.TypeSize);
                                                               end;
                                                        end;
                                       end; {end case ...}

                       NotFound := false;
                       break;
                      end else
                      begin
                        if Mode = ReadMode then
                         begin
                               UpdateMessage(rsTUFFReadOrWriteDataToRecordPrm_Msg1 + String(PrmBlock.PrmName));
                               {Если переменная имеет другой тип данных то просто перемещаем позицию в файле на следующий параметр}
                                if (PrmBlock.PrmType = tkUString) or (PrmBlock.PrmType = tkDynArray) then
                                 begin
                                   FS.Read(PrmSize, SizeOf(PrmSize));
                                   {Параметр отсутствует}
                                   FS.Position := FS.Position + PrmSize;
                                 end else
                                 begin
                                     FS.Position := FS.Position + PrmBlock.TypeSize;
                                 end;
                         end;
                      end; {end if (Fields[I].FieldType.TypeKind = PrmBlock.PrmType) then ...}
                    end; {end if UpperCase(Fields[I].Name) = UpperCase(String(PrmBlock.PrmName)) then ...}
        end else
        begin
          UpdateMessage(rsTUFFReadOrWriteDataToRecordPrm_Msg2 + Fields[I].Name + rsTUFFReadOrWriteDataToRecordPrm_Msg3);
         // exit;
        end; {end if Assigned(Fields[I].FieldType) then}
   end; {end for I := 0 to High(Fields) do}

   if NotFound and (Mode = ReadMode) then
     begin
     UpdateMessage(rsTUFFReadOrWriteDataToRecordPrm_Msg4 + String(PrmBlock.PrmName) + rsTUFFReadOrWriteDataToRecordPrm_Msg5);
     {Если параметр несуществует то перемещаем позицию в файле}
      if (PrmBlock.PrmType = tkUString) or (PrmBlock.PrmType = tkDynArray) then
       begin
         FS.Read(PrmSize, SizeOf(PrmSize));
         FS.Position := FS.Position + PrmSize;
       end else
       begin
         FS.Position := FS.Position + PrmBlock.TypeSize;
       end;
    end;
end;

...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743124
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vlad FНачинаю догадываться, - студент? курсовая?Совершенно неверно!
В общем, тем, кто начал писать про мужиков, студентов, - отвечать нет желания.
Остальным - спасибо (получилось, код приводить не буду).
Относительно "Динамический массив же не копируется через Move" - было
Move(SrcArr, DstArr[0], ...);
а нужно было
Move(SrcArr[0], DstArr[0],, ...);
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743125
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

Ну и слава богу.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743174
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registeredVlad FНачинаю догадываться, - студент? курсовая?Совершенно неверно!
В общем, тем, кто начал писать про мужиков, студентов, - отвечать нет желания.
Остальным - спасибо (получилось, код приводить не буду).
Относительно "Динамический массив же не копируется через Move" - было
Move(SrcArr, DstArr[0], ...);
а нужно было
Move(SrcArr[0], DstArr[0],, ...);хотелось бы увидеть этот код, если он вообще есть))))
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743175
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registeredОстальным - спасибо (получилось, код приводить не буду).
Относительно "Динамический массив же не копируется через Move" - было
Move(SrcArr, DstArr[0], ...);
а нужно было
Move(SrcArr[0], DstArr[0],, ...);...и будет это работать только до тех пор пока элементы массива сами не станут управляемым типом или его содержащим контейнером...
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39743183
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gssboxДелал такое использовал RTTI и дженерики, но в конечном счете пришлось отказаться от этой идеи так как тормозило при интенсивных нагрузках.
довольно много выделений памяти и цикл с поиском параметров + то что white_nigger написал

можно ещё допиливать и допиливать
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39744995
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если есть вложенная запись

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
type ta=record
s:string;
i:integer;
end;

type trec=record;
a:ta;
i:integer;
end;

var rec:trec;



То, если скопировать память переменной rec, то, вместо указателя на структуру a , может оказаться левый адрес. Вероятно, то же и с s:string; . И даже отдельное копирование переменной a не спасёт, потому что адрес затёрт. Что делать, однако?
Код привести не могу, потому что "в продакшене"... э-э, в общем, тестовый проект с просто записью и чтением из файла - работает, а реальный - нет.

Где-то так:
Код: pascal
1.
2.
3.
4.
move(str1[1],rec,length(str1));
move(str2[1],rec.a,length(str2));
setlength(rec.a.s,length(str3));
move(str3[1],rec.a.s[1],length(str3));


Крэшится на втором "move".
str1, str2, str3 - это ansistring, с данными, соответственно, rec, rec.a, rec.a.s.
...
Рейтинг: 0 / 0
25 сообщений из 45, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как сохранить в файл запись (record) с динамическими массивами?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]