Skocz do zawartości

[Delphi]Zapis/odczyt ze Strumienia


5corpio

Polecane posty

Siema mam taki jakiś dziwny problem przy odczytywaniu Stringa ze strumienia dokładnie używam klasy TFileStream. Wiadomo zapisuje najpierw długość łańcucha a potem go... a przy odczytywaniu wczytuje ilość a potem do Stringa chce wczytać tyle byte-ów ile wczytałem do zmiennej powiedzmy Int.

 

Może kodzik:P :

 

procedure TSpriteObj2d.SaveSpriteToStream(s: TFileStream);
var
 n : Integer;
 i : Integer;
begin
 { *************** }
 with fLogicData do
   begin
     s.WriteBuffer(fVisible, SizeOf(fVisible));  
     n := StrLen(PAnsiChar(fName));            
     s.WriteBuffer(n, SizeOf(n));                   
     s.WriteBuffer(fName, n);
     s.WriteBuffer(fSize, SizeOf(fSize));             //fSize to Wektor (x,y)
     s.WriteBuffer(fBlend, SizeOf(fBlend));
     s.WriteBuffer(fActSeq, SizeOf(fActSeq));
     s.WriteBuffer(fAnimSpeed, SizeOf(fAnimSpeed));
   end;

 { ************* }
 with fGeometryData do
   begin
     s.WriteBuffer(fColors, SizeOf(fColors));          //fColors : Array[0..3] of TColor4f; <- taki rekord trzymający R,G,B,A : Single;
     s.WriteBuffer(fWrap, SizeOf(fWrap));             // fWrap : Array[0..3] of TVector2d; Vector2d = (x,y : Single)
     n := StrLen(PAnsiChar(fTTex.fTextureName)); // próbowąłem też dł. pobierać przez Length ale i tak oba zwracają dobrą długość... 
     s.WriteBuffer(n, SizeOf(n));                             
     s.WriteBuffer(fTTex.fTextureName, n);             
   end;
end;

Jeszcze kodzik, który wykonuje w innym miejscu:
[delphi]
 sO := TFileStream.Create('defualtSprite.spr', fmOpenRead);
 ChrTest.fImage.LoadSpriteFromStream(sO);
 FreeAndNil(sO);

 

Jak wczytuje do zmiennej lokalnej to otrzymuje Invalid Pointer Operation jak wczytuje prosto do zmiennej gdzieś w moim rekordzie tej klasy TSpriteObj2d to wczytuje mi z dupy stringa o innej treści.

 

A Swoją drogą nie wiem czemu przy edytowaniu postów część treści zmienia się w "krzaczki" i chyba nie tylko ja to miałem... miałem to na starszej operze 9.27 i widzę, że mam nadal na Operze 9.50 :)

 

Ktoś bardziej rozgarnięty mi powie czemu takiego psikusa mam :> ?

Ot taka mini-strona moja po godzinach :)http://www.wnetrzekuchni.pl

Link do komentarza
Udostępnij na innych stronach

Spróbuj z tymi (używam ich od dawna i wszystko śmiga):

{ .: SaveStringToStream :. }
procedure SaveStringToStream(const TheString: String; S: TStream);
var
 X: Integer;
begin
 X := Length(TheString);
 S.Write(X, SizeOf(Integer));
 S.Write(TheString[1], X);
end;

{ .: LoadStringFromStream :. }
procedure LoadStringFromStream(var TheString: String; S: TStream);
var
 X: Integer;
begin
 S.Read(X, SizeOf(Integer));
 SetLength(TheString, X);
 S.Read(TheString[1], X);
end;

Link do komentarza
Udostępnij na innych stronach

E tam Force nie prawda :P Sprawdziłem i rozwiązanie Brainera działa spoko w sensie żeby użyć przed tym SetLength i wrzucić indeks [1] :P hehe ktoś mi teraz wytłumaczy mechanizm takiego działania ? Co jest zapisane pod indeksem [0] w Stringu ew. czemu indeksowana jest zawartość od 1 :> ? Bo ciekawy jestem eheh

 

Brainer dzięki :P wsumie takie metodki 2 nie kulawe są :P

 

 

Edit: Hahahah niesamowite otworzyłem Swój unit z różnymi metodami pomocniczymi i miałem tam takie metody do zapisu Stringa do strumienia :P heheh Hmmm to chyba jeszcze od Tostera je kiedyś dostałem :P

Ot taka mini-strona moja po godzinach :)http://www.wnetrzekuchni.pl

Link do komentarza
Udostępnij na innych stronach

@Brainer: Miło (i bardzo dobrze), że się starasz ale zrobiłeś "kilka" błędów

 

Po pierwsze, jak już to bajt a nie bit.

Po drugie, i tak nie jest to bajt a 4 bajty czyli zaczyna się to w stringu na pozycji s[-3]

Po trzecie, to nie licznik odwołań, a długość łańcucha

Po czwarte, licznik odwołań jest na pozycji s[-7]

Po piąte, twój sposób zapisu prawdopodobnie wywali się na stringach z D2008 i wypadałoby używać AnsiString zamiast string albo zmienić procedury odczytu/zapisu

Po szóste, cecha którą opisałeś może ulegać zmianie bo nie jest to nic oficjalnego (i takowym ulega) i trzeba to zaakcentować ;)

Po siódme, w "Delphi Almanach" niektóre informacje są błędne/nieaktualne, tak więc

Po ósme, sprawdzaj to o czym piszesz

Po dziewiąte, gratuluję zakupu "Delphi Almanach" - początek poznawanie zawiłości Delphi Object Pascala :)

soon Delphi will be only for veterans and finally we all will die at the end…

delphi.dathox.com - nowinki z świata Delphi/Pascala

only programmers and drug dealers call their customers "users"

 

Oto cisza przed burzą, Chwile się dłużą.Z gór schodzi dużo chmur ku podnóżom.Ptaki milaczą, drogi suche jak wiór się kurzą, Ptaki milczą a drogi się kurzą.

Link do komentarza
Udostępnij na innych stronach

Nie "pojechałeś" tylko "doedukowałeś" :)

soon Delphi will be only for veterans and finally we all will die at the end…

delphi.dathox.com - nowinki z świata Delphi/Pascala

only programmers and drug dealers call their customers "users"

 

Oto cisza przed burzą, Chwile się dłużą.Z gór schodzi dużo chmur ku podnóżom.Ptaki milaczą, drogi suche jak wiór się kurzą, Ptaki milczą a drogi się kurzą.

Link do komentarza
Udostępnij na innych stronach

Skoro już mam możliwość zapytania, to chciałbym się dowiedzieć, jaka jest różnica między String, AnsiString i WideString? O typie AnsiString poczytałem na 4programmers i tam jest coś takiego:

W Delphi dla Win32, typ String wskazywał na typ AnsiString; w Delphi dla .NET, typ String wskazuje na WideString

.

Tak więc dlaczego zasugerowałeś mi, żebym używał tego typu?

 

Z góry dziękuję za wyjaśnienie.

Link do komentarza
Udostępnij na innych stronach

AnsiString jest łańcuchem znaków AnsiChar gdzie znak = 1 bajt.

WideString jest łańcuchem znaków WideChar gdzie znak = 2 bajty.

 

Obecnie string = AnsiString (string jest aliasem do obecnego standardu w Delphi podobnie jak Integer = LongInt i być może w Delphi Commodore64 Integer będzie = Int64 ale to inna bajka)

 

W nowej wersji D2008 string = UnicodeString, nowy typ będzie nieco inny od WideString (co prawda dość podobny bo każdy znak też ma 2 bajty) ponieważ będzie szybszy i zarządzany jak teraźniejszy AnsiString.

 

Według zapewnień CodeGear nie będzie większych problemów z tą podmianką AnsiString na UnicodeString jednak niewielkich korekt w kodzie należy dokonać już teraz.

 

Dlaczego radze pozamieniać string na AnsiString? Po pierwsza zajmują mniej miejsca w pamięci i ze względu na rozmiar znaków wszelakie operacje na nich są szybsze (nie wspominając już o wygodzie używania stringów jako tablic do danych wszelakich ^^). Jedynym powodem dla którego warto używać UnicodeString to konieczność obsługi japońskiego czy chińskiego ^^ (ewentualna furtka do implementacji "języków świata" dla naszego programu w przyszłości).

 

Unicode będzie można wyłączyć w D2008 i przywrócić stringi jako AnsiString jednak wtedy przestaną działać wzorce "generics" dla klas (a klasy z classes będą posiadały pewne ułatwienia do zarządzania pomiędzy AnsiString/UnicodeString jak i całe przebudowane VCL).

 

Gra warta świeczki :) - jeśli nic dziwnego nie robisz ze stringami nie ma się o co martwić - skoro kompilator i IDE Delphi dało się już skompilować z nowymi stringami w naszych programach wszystko powinno być OK. Trzeba tylko zrobić korektę przy "binarnych" operacjach jak zapis/odczyt pliku.

soon Delphi will be only for veterans and finally we all will die at the end…

delphi.dathox.com - nowinki z świata Delphi/Pascala

only programmers and drug dealers call their customers "users"

 

Oto cisza przed burzą, Chwile się dłużą.Z gór schodzi dużo chmur ku podnóżom.Ptaki milaczą, drogi suche jak wiór się kurzą, Ptaki milczą a drogi się kurzą.

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...