Błędne działanie kodu pod Delphi 10.2.3

0

Witam serdecznie

Mam problem z błędnie wykonującym się kodem po przejściu z Turbo Pascal na Delphi 10.2.3. Kod który wykonuję się nieprawidłowo poniżej:

var
  Form2: TForm2;
  Stream:TMemoryStream;
  l:TStringList;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
  s,sx: String;
  i: Integer;
  n: Word;
  b: Byte;
  P :Integer;
begin
  n := l.Count;
  P:= Stream.Position;
  Stream.Write(n, 2);
  for i := 0 to l.Count - 1 do
  begin
    s := l[i];
    n := Length(s);
    Stream.Write(n, 2);
    Stream.Write(s[1], n);
    b := 13;
    if i <> l.Count - 1 then Stream.Write(b, 1);
  end;
  b := 0;
  Stream.Write(b, 1);

// odczyt danych

  SetLength(sx,n);
  Stream.Position := P+4;
  Stream.Read(sx[1],n);
  ShowMessage(sx);

end;

procedure TForm2.FormCreate(Sender: TObject);
begin
Stream := TMemoryStream.Create;

l:=TStringList.Create;
l.Add('Napis do obrobki.');
end;

end.

Po zapisaniu do Stream i po ponownym odczytaniu otrzymuję tylko kilka danych, kod w Turbo Delphi wykonuje się prawidłowo

Z góry dziękują za pomoc.

Pozdrawiam

0

Po to klasa TStrings ma metody SaveToStream i LoadFromStream, aby z nich korzystać. Po co piszesz swoje?

// odczyt danych
 
  SetLength(sx,n);
  Stream.Position := P+4;
  {..}

A jaką wartość ma P w tym miejscu?

Stream.Write(n, 2);

Dlaczego zgadujesz jaki ma rozmiar zmienna n, zamiast skorzystać z funkcji SizeOf?

Stream.Write(s[1], n);

A jaki rozmiar ma typ Char? Coś mi się wydaje, że nie jest to jeden bajt.

0
furious programming napisał(a):

Po to klasa TStrings ma metody SaveToStream i LoadFromStream, aby z nich korzystać. Po co piszesz swoje?

SaveToStream(Stream) i tak na końcu kończy się funkcją Stream.Write(Buffer, Offset, Count);

więc użyto bezpośrednio stream.write.

SetLength(sx,n);
Stream.Position := P+4;

Na początku jest zapamiętywana pozycja Stream w zmiennej P, gdyż funkcja która mi nie działa obrabia część stream'a ustawionego na danej pozycji

Dlaczego zgadujesz jaki ma rozmiar zmienna n, zamiast skorzystać z funkcji SizeOf?

Zmiana na SizeOf(..) nie pomaga.

s[1] jest wskazaniem na 1 char w stringu (Buffer)

Tworzony stream jest poskładany z różnych parametrów i zapewne nie poradzi sobie z tym zwykły SaveStream, Stream zapisywany do pamięci jest prawidłowo, żle jest natomiast odczytywany. W Turbo Delphi ten sam kod działa bez żadnych problemów.

Pozdrawiam

1

String w Turbo Delphi i String w Delphi 10 to różne typy zmiennych. Ansistring rozwiązało problem.

1
lukardsoft napisał(a):

Zmiana na SizeOf(..) nie pomaga.

No właśnie pomaga, bo za jego pomocą możesz prawidłowo określić rozmiar łańcucha liczony w bajtach. Pisałem w poprzednim poście, że zgadujesz jaki rozmiar ma Char, zamiast go pobrać za pomocą SizeOf i pomnożyć przez liczbę znaków w ciągu.

[…] Stream zapisywany do pamięci jest prawidłowo, żle jest natomiast odczytywany.

No nie jest zapisywany prawidłowo, bo do strumienia zapisujesz połowę znaków każdego ciągu z listy.

W Turbo Delphi ten sam kod działa bez żadnych problemów.

Ten kod działałby bez problemów w dowolnej wersji środowiska, gdybyś nie używał magicznych liczb. Nawet w przypadku zupełnie własnej implementacji tego typu serializacji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1