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

Тема в разделе "Delphi - Система", создана пользователем Василий, 22 фев 2015.

  1. Василий

    Регистрация:
    22 фев 2015
    Сообщения:
    9
    Симпатии:
    0
    На http://forum.codeby.net/lofiversion/index.php?t36696.html
    есть сохранение на диск. В Delphi XE3 работать отказывается.
    Чтение из файла работает. Пришлось к Char и String добавить Ansi
    Прошу помощи
    Часть кода:
    Код (Delphi):

    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 версии без проблем
     
    #1 Василий, 22 фев 2015
    Последнее редактирование модератором: 22 фев 2015
  2. -master-

    -master- Well-Known Member

    Регистрация:
    14 янв 2012
    Сообщения:
    629
    Симпатии:
    18
    а что такое len?
     
  3. Василий

    Регистрация:
    22 фев 2015
    Сообщения:
    9
    Симпатии:
    0
    Я пропустил 3 первых строки:
    Код (Delphi):
    Result := 0;
     
      len := Length(strArray);
     
      if (len < 1) then Exit;
     
         ms := TMemoryStream.Create;
    strArray - сохраняемый в файл массив строк, len - число строк в этом массиве.
    Это описано в http://forum.codeby.net/lofiversion/index.php?t36696.html
     
    #3 Василий, 22 фев 2015
    Последнее редактирование модератором: 23 фев 2015
  4. -master-

    -master- Well-Known Member

    Регистрация:
    14 янв 2012
    Сообщения:
    629
    Симпатии:
    18
    тогда не мудрено что ошибка, сами то как понимаете эту строку
    ms.WriteBuffer(Pointer(len),SizeOf(Integer));
     
  5. Василий

    Регистрация:
    22 фев 2015
    Сообщения:
    9
    Симпатии:
    0
    Если я правильно понял, то это запись данных в текущую позицию потока. Вопрос вот в чем:
    В Turbo Delphi 2006 работает, а Delphi XE3 нет! На этой строке только Delphi XE3 выдает ошибку. Как исправить эту ошибку.
    Вот вся процедура:
    Код (Delphi):
    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
     
    #5 Василий, 23 фев 2015
    Последнее редактирование модератором: 23 фев 2015
  6. blackstrip

    blackstrip Member

    Регистрация:
    20 фев 2015
    Сообщения:
    12
    Симпатии:
    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 какого нибудь.
     
  7. Василий

    Регистрация:
    22 фев 2015
    Сообщения:
    9
    Симпатии:
    0
    Заработало, но не так как надо. Записанный файл не читается. Посмотрел его: Строка REZ_ID записана странно - символы чередуются с нулевыми байтами! Не могу понять, почему в Turbo Delphi 2006 работает, а Delphi XE3 нет!
     
  8. -master-

    -master- Well-Known Member

    Регистрация:
    14 янв 2012
    Сообщения:
    629
    Симпатии:
    18
    потому что юникод
     
  9. Василий

    Регистрация:
    22 фев 2015
    Сообщения:
    9
    Симпатии:
    0
    Спасибо, за подсказку, методом "научного тыка" получил следующее:
    Код (Delphi):
    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;
     
    #9 Василий, 24 фев 2015
    Последнее редактирование модератором: 25 фев 2015
  10. vital

    vital Больной Компом Детектед

    Регистрация:
    29 янв 2006
    Сообщения:
    2.469
    Симпатии:
    27
    @Василий заколебался я вместо тебя теги кода расставлять
     
  11. Василий

    Регистрация:
    22 фев 2015
    Сообщения:
    9
    Симпатии:
    0
    Все равно, спасибо!
     
Загрузка...

Поделиться этой страницей