2013-02-11 15 views
6

Czytałem dużo dyskusji na tutaj dotyczące pisania ciągi do TMemoryStream i zapisywanie do pliku i odczyt ciągów powrotem do TMemoryStreamwprowadzenie napisów do TMemoryStream

Nie wiem co zrobiłem źle tutaj, ale zarówno w My SaveData lub moje LoadData są błędne. Mogę sprawdzić wartość tytułu, zanim zadzwonię do SaveData i spełni to, czego się spodziewam. Jednak, gdy wywołuję LoadData i sprawdzam wartość tytułu, jest to śmieci. Może ktoś mi powiedzieć co zrobiłem źle proszę

procedure SaveData(FileName: TFileName); 
var 
MemStr: TMemoryStream; 
Title: String; 
begin 
MemStr:= TMemoryStream.Create; 
try 
MemStr.Seek(0, soFromBeginning); 
WriteStreamStr(MemStr, TItle); 
MemStr.SaveToFile(FileName); 
finally 
MemStr.Free; 
end; 
end; 

procedure LoadData(FileName: TFileName); 
var 
MemStr: TMemoryStream; 
Title: String; 
begin 
MemStr:= TMemoryStream.Create; 
try 
    MemStr.LoadFromFile(FileName); 
    MemStr.Seek(0, soFromBeginning); 
    Title := ReadStreamStr(MemStr); 
finally 
    MemStr.Free; 
    end; 
end; 



procedure WriteStreamInt(Stream : TStream; Num : integer); 
{writes an integer to the stream} 
begin 
Stream.WriteBuffer(Num, SizeOf(Integer)); 
end; 

procedure WriteStreamStr(Stream : TStream; Str : string); 
{writes a string to the stream} 
var 
StrLen : integer; 
begin 
{get length of string} 
StrLen := Length(Str); 
{write length of string} 
WriteStreamInt(Stream, StrLen); 
if StrLen > 0 then 
{write characters} 
Stream.Write(Str[1], StrLen); 
end; 


function ReadStreamInt(Stream : TStream) : integer; 
{returns an integer from stream} 
begin 
Stream.ReadBuffer(Result, SizeOf(Integer)); 
end; 

function ReadStreamStr(Stream : TStream) : string; 
{returns a string from the stream} 
var 
LenStr : integer; 
begin 
Result := ''; 
{get length of string} 
LenStr := ReadStreamInt(Stream); 
{set string to get memory} 
SetLength(Result, LenStr); 
{read characters} 
Stream.Read(Result[1], LenStr); 
end; 
+1

Dlaczego nie spróbować "TStringStream"? – TLama

+1

Lub dać TStringList.SaveToFile/LoadFromFile spróbować? – iamjoosy

+0

Tak, cały kod wydaje się bezsensowny, ponieważ 'TStrings' ma' SaveToStream' i 'LoadFromStream'. A jeśli nie jest to idealne dopasowanie do prawdziwej aplikacji, wtedy zajęcia czytelnika/pisarza wykonają zadanie. –

Odpowiedz

17

Podczas korzystania

Stream.Write(Str[1], StrLen); 

piszesz pierwsze StrLen bajtów do strumienia. Ale dane w postaci ciągu znaków (Unicode) są w rzeczywistości StrLen * SizeOf(Char) bajtów (musisz wziąć rozmiar typu char pod uwagę). Dlatego następujące czynności powinny działać:

Stream.Write(Str[1], StrLen * SizeOf(Str[1])); 

To samo dotyczy odczytu danych z powrotem ze strumienia.

+15

'ByteLength (Str)' istnieje dla tego –

+0

To zadziała! Dziękuję Ci! – JakeSays

Powiązane problemy