О сохранении массива строк на диск

22.02.2015
8
0
#1
На
Для просмотра контента необходимо: Войти или зарегистрироваться

есть сохранение на диск. В Delphi XE3 работать отказывается.
Чтение из файла работает. Пришлось к Char и String добавить Ansi
Прошу помощи
Часть кода:
Код:
ms.Seek(0,soFromBeginning);
  // записали имя ресурса
  // чтобы потом (при чтении) быть уверенным что это наш массив
  ms.WriteBuffer(RES_ID,Length(RES_ID)*SizeOf(ansiChar));
  // записали общую длину массива
  ms.WriteBuffer(Pointer(len),SizeOf(Integer)); // ОШИБКА ЗДЕСЬ код ошибки $C00000005
  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(ansiChar));
    end;
В 2006 версии без проблем
 
Последнее редактирование модератором:
22.02.2015
8
0
#3
Я пропустил 3 первых строки:
Код:
Result := 0;
 
  len := Length(strArray);
 
  if (len < 1) then Exit;
 
	 ms := TMemoryStream.Create;
strArray - сохраняемый в файл массив строк, len - число строк в этом массиве.
Это описано в
Для просмотра контента необходимо: Войти или зарегистрироваться
 
Последнее редактирование модератором:

-master-

Well-known member
14.01.2012
616
12
#4
тогда не мудрено что ошибка, сами то как понимаете эту строку
ms.WriteBuffer(Pointer(len),SizeOf(Integer));
 
22.02.2015
8
0
#5
Если я правильно понял, то это запись данных в текущую позицию потока. Вопрос вот в чем:
В Turbo Delphi 2006 работает, а Delphi XE3 нет! На этой строке только Delphi XE3 выдает ошибку. Как исправить эту ошибку.
Вот вся процедура:
Код:
Procedure SaveToFile( var strArray: TStringArray);
const  RES_ID = 'MAIN_FILE';
var ms: TMemoryStream;i,len: Integer;s: ansistring;Result:integer;
begin  
Result := 0;  
len := Length(strArray);  
if (len < 1) then Exit;	 
ms := TMemoryStream.Create;  
ms.Seek(0,soFromBeginning);  // записали имя ресурса  // чтобы потом (при чтении) быть уверенным что это наш массив  
ms.WriteBuffer(RES_ID,Length(RES_ID)*SizeOf(ansiChar));  // записали общую длину массива  
ms.WriteBuffer(Pointer(len),SizeOf(Integer));  
Result := len;  
for i := Low(strArray) to High(strArray) do	begin
	  len := Length(strArray);	  // записали длину i-той строчки 
	 ms.WriteBuffer(Pointer(len),SizeOf(Integer));	  // записали i-тую строчку
	  if (len > 0) then
		ms.WriteBuffer(strArray[1],len*SizeOf(ansiChar)); 
   end;  
ms.Seek(0,soFromBeginning);  
try	
ms.SaveToFile(frmMain.FName); 
 except  
  Result := 0; // а вдруг не удалось записать файл?
  end;
  ms.Free;
end;
Процедура чтения работает в Turbo Delphi 2006 и Delphi XE3
 
Последнее редактирование модератором:
20.02.2015
12
3
#6
ms.WriteBuffer(Pointer(len),SizeOf(Integer));

Зачем Pointer(len)? Если len был равен 45, то Pointer(len) создаст указатель на байт номер 45 в памяти (а это совсем не переменная len, и не ее адрес расположения в памяти).

ms.WriteBuffer(len,SizeOf(Integer)); должно сработать.

А если нужно где-то адрес указывать - то, наверное, DWORD(Addr(len)) или DWORD(@len) можно было бы для 32 бит, а для 64 бит там 64-битные поинтеры, типа QWORD какого нибудь.
 
22.02.2015
8
0
#7
Заработало, но не так как надо. Записанный файл не читается. Посмотрел его: Строка REZ_ID записана странно - символы чередуются с нулевыми байтами! Не могу понять, почему в Turbo Delphi 2006 работает, а Delphi XE3 нет!
 
22.02.2015
8
0
#9
Спасибо, за подсказку, методом "научного тыка" получил следующее:
Код:
Procedure SaveToFile( var strArray: TStringArray);
 
const
 
RES_ID = 'MAIN_FILE';
 
var
 
ms: TMemoryStream;
 
i,len: Integer;
 
s: ansistring;
 
Result:integer;
 
begin
 
Result := 0;
 
len := Length(strArray);
 
if (len < 1) then Exit;
 
ms := TMemoryStream.Create;
 
ms.Seek(0,soFromBeginning);
 
len := Length(RES_ID);
 
ms.WriteBuffer(RES_ID[1],Len*SizeOf(ansiChar));
 
len := Length(strArray);
 
ms.WriteBuffer(len,SizeOf(Integer));
 
Result := len;
 
for i := Low(strArray) to High(strArray) do
 
begin
 
len := Length(strArray);
 
ms.WriteBuffer(len,SizeOf(Integer));
 
if (len > 0) then
 
ms.WriteBuffer(strArray[1],len*SizeOf(ansiChar));
 
end;
 
ms.Seek(0,soFromBeginning);
 
try
 
ms.SaveToFile(frmMain.FName);
 
except
 
Result := 0;
 
end;
 
ms.Free;
 
end;
 
Последнее редактирование модератором: