2013-02-11 19 views
6

Tôi đã đọc rất nhiều cuộc thảo luận về đây liên quan đến chuỗi văn bản cho một TMemoryStream và tiết kiệm để nộp và đọc chuỗi lại vào TMemoryStreamViết dây để TMemoryStream

Tôi không biết những gì tôi đã làm sai ở đây, nhưng một trong hai của tôi SaveData hoặc LoadData của tôi là sai. Tôi có thể kiểm tra giá trị của Tiêu đề trước khi tôi gọi SaveData và nó giữ những gì tôi mong đợi. Tuy nhiên, khi tôi gọi LoadData và kiểm tra giá trị của Title, nó là rác. bất cứ ai có thể cho tôi biết những gì tôi đã làm sai xin

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

Tại sao bạn không thử 'TStringStream'? – TLama

+1

Hoặc thử TStringList.SaveToFile/LoadFromFile? – iamjoosy

+0

Có, tất cả các mã có vẻ vô nghĩa vì 'TStrings' có' SaveToStream' và 'LoadFromStream'. Và nếu đó không phải là sự phù hợp hoàn hảo cho ứng dụng thực tế, thì các lớp người đọc/người viết sẽ thực hiện công việc. –

Trả lời

17

Khi bạn sử dụng

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

bạn đang viết StrLen byte đầu tiên cho luồng dữ liệu. Nhưng dữ liệu chuỗi (unicode) thực sự là StrLen * SizeOf(Char) bytes (bạn phải tính kích thước của loại char vào tài khoản). Vì vậy, sau đây sẽ hoạt động:

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

Tương tự khi đọc dữ liệu trở lại từ luồng.

+15

'ByteLength (Str)' tồn tại cho –

+0

Điều đó sẽ hoạt động! Cảm ơn bạn! – JakeSays