S
semantics
есть массив или список типа string. Длина строк меняется при работе программы.
Как сохранять этот массив на диск, не фиксируя длину строк?
Как сохранять этот массив на диск, не фиксируя длину строк?
🚨 29 мая стартует курс «Пентест Active Directory: от теории к практике» от Академии Кодебай
🔍 Изучите реальные техники атак на инфраструктуру Active Directory: от первоначального доступа до полной компрометации.
🛠️ Освойте инструменты, такие как BloodHound, Mimikatz, CrackMapExec и другие.
🧪 Пройдите практические лабораторные работы, имитирующие реальные сценарии атак.
🧠 Получите знания, которые помогут вам стать востребованным специалистом в области информационной безопасности.После старта курса запись открыта еще 10 дней Подробнее о курсе ...
Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе
Безусловно, самый "незаморочистый" способ сохранения в файл динамического массива строк, это использование промежуточного Стринг листа (TStringList)есть массив или список типа string. Длина строк меняется при работе программы.
Как сохранять этот массив на диск, не фиксируя длину строк?
//...
type
// Объявляем тип (Delphi "не любит" работать с <array of string> как параметр внутри процедуры )
TStringArray = array of string;
TOptArrayCommand = (opSaveToFile, opLoadFromFile); // Опции управления функцией
//...
var
SArray: TStringArray;
implementation
function ArrayOperation1(const FileName: string; var strArray: TStringArray; Opt: TOptArrayCommand):Integer;
var
SList: TStringList;
i: Integer;
begin
Result := 0;
case Opt of
opSaveToFile : begin // Запись в файл
if (Length(strArray) < 1) then Exit;
SList := TStringList.Create;
for i := Low(strArray) to High(strArray) do
SList.Add(strArray[i]);
SList.SaveToFile(FileName);
Result := SList.Count;
SList.Free;
end;
opLoadFromFile : begin // Чтение из файла
// обнулили массив
SetLength(strArray,0);
if not FileExists(FileName) then Exit;
SList := TStringList.Create;
SList.LoadFromFile(FileName);
SetLength(strArray,SList.Count);
for i := Low(strArray) to High(strArray) do
strArray[i] := SList[i];
Result := SList.Count;
SList.Free;
end;
end;
end;
//...
type
// Объявляем тип (Delphi "не любит" работать с <array of string> как параметр внутри процедуры )
TStringArray = array of string;
TOptArrayCommand = (opSaveToFile, opLoadFromFile); // Опции управления функцией
//...
var
SArray: TStringArray;
implementation
function ArrayOperation2(const FileName: string; var strArray: TStringArray; Opt: TOptArrayCommand):Integer;
const
RES_ID = 'MYSTRARRAY';
var
ms: TMemoryStream;
i,len: Integer;
s: string;
begin
Result := 0;
case Opt of
opSaveToFile : begin // Запись в файл
len := Length(strArray);
if (len < 1) then Exit;
ms := TMemoryStream.Create;
ms.Seek(0,soFromBeginning);
// записали имя ресурса
// чтобы потом (при чтении) быть уверенным что это наш массив
ms.WriteBuffer(RES_ID,Length(RES_ID)*SizeOf(Char));
// записали общую длину массива
ms.WriteBuffer(Pointer(len),SizeOf(Integer));
Result := len;
for i := Low(strArray) to High(strArray) do
begin
len := Length(strArray[i]);
// записали длину i-той строчки
ms.WriteBuffer(Pointer(len),SizeOf(Integer));
// записали i-тую строчку
if (len > 0) then
ms.WriteBuffer(strArray[i][1],len*SizeOf(Char));
end;
ms.Seek(0,soFromBeginning);
try
ms.SaveToFile(FileName);
except
Result := 0; // а вдруг не удалось записать файл?
end;
ms.Free;
end;
opLoadFromFile : begin // Чтение из файла
// обнулили массив
SetLength(strArray,0);
if not FileExists(FileName) then Exit;
ms := TMemoryStream.Create;
ms.LoadFromFile(FileName);
ms.Seek(0,soFromBeginning);
// прочитали имя ресурса
SetLength(s,Length(RES_ID));
ms.ReadBuffer(s[1],Length(RES_ID)*SizeOf(Char));
// Убедились что это именно то что мы хотим
// прочитать в массив строк
if (s <> RES_ID) then
begin
ms.Free;
Exit;
end;
// прочитали общую длину массива
ms.ReadBuffer(Pointer(len),SizeOf(Integer));
// выставили длину массива
SetLength(strArray,len);
for i := Low(strArray) to High(strArray) do
begin
// прочитали длину i-той строчки
ms.ReadBuffer(Pointer(len),SizeOf(Integer));
if (len > 0) then
begin
// выставили длину i-того элемента массива
SetLength(strArray[i],len);
// прочитали i-тую строчку
ms.ReadBuffer(strArray[i][1],len*SizeOf(Char));
end
else
strArray[i] := '';
end;
Result := Length(strArray);
ms.Free;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ResultCount: Integer;
begin
ResultCount := ArrayOperation1('c:\arraydata1.txt',SArray,opSaveToFile);
ShowMessage(IntToStr(ResultCount));
ResultCount := ArrayOperation1('c:\arraydata1.txt',SArray,opLoadFromFile);
ShowMessage(IntToStr(ResultCount));
if (ResultCount > 0) then
ShowMessage(SArray[0]);
ResultCount := ArrayOperation2('c:\arraydata2.txt',SArray,opSaveToFile);
ShowMessage(IntToStr(ResultCount));
ResultCount := ArrayOperation2('c:\arraydata2.txt',SArray,opLoadFromFile);
ShowMessage(IntToStr(ResultCount));
if (ResultCount > 0) then
ShowMessage(SArray[0]);
end;
Тип Pointer в XE3 имеет разную размерность для Win32 и Win64.ms.WriteBuffer(Pointer(len),SizeOf(Integer)); ошибка $C0000005.
// ...
type
// Объявляем тип (Delphi "не любит" работать с <array of string> как параметр внутри процедуры )
TStringArray = array of AnsiString;
TOptArrayCommand = (opSaveToFile, opLoadFromFile); // Опции управления функцией
// ...
function ArrayOperation2(const FileName: AnsiString; var strArray: TStringArray;
Opt: TOptArrayCommand): Integer;
const
RES_ID: PAnsiChar = 'MYSTRARRAY';
var
ms: TMemoryStream;
i, len,n: Integer;
s: AnsiString;
begin
Result := 0;
n := StrLen(RES_ID);
case Opt of
opSaveToFile:
begin // Запись в файл
len := Length(strArray);
if (len < 1) then
Exit;
ms := TMemoryStream.Create;
ms.Seek(0, soFromBeginning);
// записали имя ресурса
// чтобы потом (при чтении) быть уверенным что это наш массив
ms.WriteBuffer(RES_ID^, n { SizeOf(RES_ID)});
// записали общую длину массива
ms.WriteBuffer(len, SizeOf(Integer));
Result := len;
for i := Low(strArray) to High(strArray) do
begin
len := Length(strArray[i]);
// записали длину i-той строчки
ms.WriteBuffer(len, SizeOf(Integer));
// записали i-тую строчку
if (len > 0) then
ms.WriteBuffer(PAnsiChar(strArray[i])^, len);
end;
ms.Seek(0, soFromBeginning);
try
ms.SaveToFile(FileName);
except
Result := 0; // а вдруг не удалось записать файл?
end;
ms.Free;
end;
opLoadFromFile:
begin // Чтение из файла
// обнулили массив
SetLength(strArray, 0);
if not FileExists(FileName) then
Exit;
ms := TMemoryStream.Create;
ms.LoadFromFile(FileName);
ms.Seek(0, soFromBeginning);
// прочитали имя ресурса
SetLength(s, n);
ms.ReadBuffer(s[1], n);
// Убедились что это именно то что мы хотим
// прочитать в массив строк
if (s <> RES_ID) then
begin
ms.Free;
Exit;
end;
// прочитали общую длину массива
ms.ReadBuffer(len, SizeOf(Integer));
// выставили длину массива
SetLength(strArray, len);
for i := Low(strArray) to High(strArray) do
begin
// прочитали длину i-той строчки
ms.ReadBuffer(len, SizeOf(Integer));
if (len > 0) then
begin
// выставили длину i-того элемента массива
SetLength(strArray[i], len);
// прочитали i-тую строчку
ms.ReadBuffer(strArray[i][1], len);
end
else
strArray[i] := '';
end;
Result := Length(strArray);
ms.Free;
end;
end;
end;
При посте Delphi-кода пожалуйста пользуйтесь тэгами (в редакторе Кнопочка "Код")Спасибо! Я примерно так и доработал Вашу идею:
Procedure SaveToFile( var strArray: TStringArray);
Имелась в виду не сама Ваша операционная система, а целевая платформа указанная в свойствах проекта, в опциях компилятораКстати Win 7 32 bit.
Обучение наступательной кибербезопасности в игровой форме. Начать игру!