procedure PutStr(AStr: String; AStream: TStream); VAR Len : Integer; begin Len := Length(AStr); AStream.Write(Len,SizeOf(Len)); if Len > 0 then AStream.Write(Astr[1],Len); <---- skriver i princippet bare et array of byte end;
uhhh. Jeg kan ikke rigtigt lide de dynamiske arrays. Det er sikkert bare konservative mig, men er de ikke ret sløve? Hvad med at prøve at skrive
aData.Read(Buffer[0],aData.Size);
I øvrigt er der noget rod med aData.Size. Der er ingen garanti for at størrelsen holder sig under 1kb. Se eksempel hvor jeg justerer antallet af bytes i denne simple filkopiering
procedure TfrmMain.Button1Click(Sender: TObject); var lgd : integer; iStream, oStream : TFileStream; Buffer : TBufferType; begin lgd := sizeof(TBufferType); iStream := TFileStream.Create('c:\eksperten.pas',fmOpenRead); oStream := TFileStream.Create('c:\eksperten.out',fmCreate); try while iStream.Position < iStream.Size do begin if iStream.Size - iStream.Position < lgd then // EOS lgd := iStream.Size - iStream.Position; iStream.ReadBuffer(Buffer[0],lgd); oStream.WriteBuffer(Buffer[0],lgd); end; finally iStream.Free; oStream.Free; end; end;
Hvad er det man checker på når man skriver "if iStream.Size - iStream.Position < lgd then" ??? Altså forstår ikke hvad der menes med size og position men jeg har så heller ikke forstand på streaming :/ kunne godt tænke mig et par tutorials i den sammenhæng...
I realiteten tjekker jeg om der er End Of Stream. Position er TStreams svar på seek() og indikerer hvor langt man er i læsning af streamen.
I ovenstående (og der er sikkert mere elegante løsninger) tjekker jeg om der er nok data i streamen til at læse 1 kb over i bufferen. Hvis der er mindre, så nøjes jeg med det (ensbetydende at man har nået End Of Stream)
Konceptet streaming kunne godt indikere at der ikke var en ende på data, men det er der og størrelsen kan findes via Size-propertyen.
Den store fordel med streaming kontra "assignfile/reset/rewrite/closefile" er, at man kan nedarve fra et baseobjekt.
Det betyder at det er lige meget om data kommer fra en TMemorystream eller en TFileStream eller noget helt tredie. De nedarver alle fra TStream og har alle de samme attributter/metoder (eng: properties/methods).
Ulempen er tekstfiler der læses linie for linie. De er noget sværere at læse med en stream. Der findes godtnok en TStringStream, men enten har jeg ikke fundet ud af hvordan den virker eller så virker den bare ikke til formålet.
MartinLind: Jeg har prøvet at teste din func, men kan ikke få den til at virke. Jeg går ud fra at det er fordi jeg creater AStream forkert ? jeg får en "Abstract Error", ved linien: AStream.Write(Len,SizeOf(Len));
procedure TForm1.Button3Click(Sender: TObject); Var AStream : TStream ; Len : Integer; AStr, BStr : String ; begin AStream := TStream.Create ;
AStr := 'Test' ; Len := Length(AStr);
AStream.Write(Len,SizeOf(Len)); if Len > 0 then AStream.Write(Astr[1],Len); // <---- skriver i princippet bare et array of byte AStream.Read(Bstr[1], Len); Label8.Caption := BStr ;
hrc: det er en smart måde at læse på, og jeg vil også bruge den, hvis jeg ikke kan få det til at virke med dynamiske arrays. Jeg bruger arrayet til at kalde en anden funktion, som skal kaldes med et Array, med den længde som Streamen har, så hvis jeg læser det ind i et statisk array, bliver jeg alligevel nød til at lægge det over i et dynamisk, for at få den rigtige længde på arrayet :-)
Her er ikke kommet nogle kommentarer, svar længe så jeg lukker spørgsmålet
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.