我正在嘗試從 TMemoryStream 中讀取兩個不同長度的字串,但兩個流最終的長度相同。因此,例如,如果第一個字串是“abcdefghijkl”,第二個是“wxyz”,那么我為第二個字串得到的值是“wxyzefghijkl”(我的新字串的前四個字符(“wxyz”)緊隨其后由第一個字串中未被 'wxyz' 替換的剩余字符
我的代碼是:-
var
L : LongInt
S : string;
...
msRecInfo.Position := 0;
msRecInfo.Read(L, SizeOf(L)); // read size of following string ...
SubStream.Clear;
SubStream.CopyFrom(msRecInfo, L); // copy next block of data to a second TMemoryStream
if (L > 0) then S := StreamToString(SubStream); //convert the stream into a string
msRecInfo.Read(L, SizeOf(L)); // get size of following string ...
SubStream.CopyFrom(msRecInfo, L);
if (L > 0) then S := StreamToString(SubStream);
我已經為此奮斗了幾個小時,但沒有成功。誰能指出我做錯了什么?
uj5u.com熱心網友回復:
您沒有SubStream.Clear()在第二次呼叫SubStream.CopyFrom(). 因此,第一次呼叫StreamToString(SubStream)離開SubStream.Position流的末尾,隨后SubStream.CopyFrom()將更多資料添加到流中,保留現有資料。然后后續StreamToString(SubStream)從 讀取所有資料SubStream。
另外,請注意,如果L將0其傳遞給SubStream.CopyFrom(),它將復制整個 msRecInfo流。這是記錄在案的行為:
https://docwiki.embarcadero.com/Libraries/en/System.Classes.TStream.CopyFrom
如果 Count 為 0,則 CopyFrom 在讀取之前將 Source 位置設定為 0,然后將 Source 的全部內容復制到流中。如果 Count 大于或小于 0,CopyFrom 從 Source 中的當前位置讀取。
所以,你需要提高你的L > 0支票,例如:
msRecInfo.Read(L, SizeOf(L));
if (L > 0) then
begin
SubStream.Clear;
SubStream.CopyFrom(msRecInfo, L);
S := StreamToString(SubStream);
end
else
S := '';
我建議將此邏輯包裝成一個可重用的函式,例如:
var
L : LongInt;
S : string;
function ReadString: string;
begin
msRecInfo.Read(L, SizeOf(L)); // read size of following string ...
if (L > 0) then
begin
SubStream.Clear;
SubStream.CopyFrom(msRecInfo, L); // copy next block of data to a second TMemoryStream
Result := StreamToString(SubStream); //convert the stream into a string
end else
Result := '';
end;
begin
...
msRecInfo.Position := 0;
S := ReadString;
S := ReadString;
...
雖然,如果可行,我建議完全擺脫SubStream,更新StreamToString()以L作為輸入引數,以便您可以直接讀取stringfrom msRecInfo,例如:
msRecInfo.Read(L, SizeOf(L));
S := StreamToString(msRecInfo, L);
TMemoryStream如果可以避免,則無需第二次。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/460928.html
