09. juli 1999 - 20:35Der er
9 kommentarer og 1 løsning
100 points: Effektiv måde at indlæse en STOR fil til en streng
Jeg forsøger at indlæse hele indholdet af en fil der meget vel kan være større end en mb til en variabel af typen string. Filen kan indeholde null-værdier (#0) som skal behandles som alle andre værdier. (Dvs almindelige null-terminerede datatyper som PChar dur IKKE)
I det følgende er Data og TempStr begge af typen String og Buffer er et array med 65536 elementer af typen char. Problemmet er at i takt med at Data bliver længere og længere bliver det langsomere og langsomere. (Dvs. første 20 % tager måske 2 sekunder, næste 20% tager så måske 5 sekunder....)
repeat BlockRead(InFile, Buffer, 65536, ActualRead); TempStr := ''''; For B := 0 to ActualRead-1 do begin TempStr := TempStr + Buffer[B] end; Data := Data + TempStr; Inc(Stat1, ActualRead); until eof(InFile);
Er der nogen der kan give en god måde at indlæse HELE filen til Data på een gang. Jeg har nemlig en teori om at Data bliver fragmenteret pga de mange omgange den bliver opbygget over.
Der bliver investeret massivt i AI. Teknologien er mere tilgængelig end nogensinde, og ambitionerne er høje. Alligevel oplever mange virksomheder, at resultaterne udebliver.
Her er et forslag med StreamObjects. Hvis du prøver at aflæse DataString, får du kun tekst ud frem til den første #0, men den indeholder hele filen alligevel. Med Position og ReadString, kan du manøvrere rundt i strengen.
procedure TForm1.Button1Click(Sender: TObject); var MinFil:TFileStream; var MinMemStream:TMemoryStream; var MinStringStream:TStringStream; var streng:string;
begin MinFil:=TFileStream.Create('c:\kjempefil.bin',fmOpenRead); MinMemStream:=TMemoryStream.Create; MinStringStream:=TStringStream.Create(streng); MinMemStream.LoadFromStream (MinFil); MinStringStream.CopyFrom(MinMemStream,MinMemStream.Size); // gør et eller andet med MinStringStream.DataString; // gør et eller andet med MinStringStream.Position; // gør et eller andet med MinStringStream.ReadString; // gør et eller andet med MinStringStream.WriteString; showmessage (IntToStr(length(MinStringStream.DataString))); MinStringStream.Free; MinMemStream.Free; MinFil.Free; end;
P.S. Nu skriver du godtnok 100pt, men du er noteret for 0.
Mange tak for forslaget - jeg har ikke lige tid til at kigge på det nu her - så du skal nok ikke forvente en dom inden i morgen :)
Grunden til jeg har sat den til 0 points er at hvis den ikke blev besvaret vill jeg ikke have mistet nogle points. Hvis jeg får noget der kan bruges skal vedkommende nok få sine points :)
Oh ja - jeg bruger copy til at snuppe korte delstrenge (der også kan indeholde #0 :) fra det store hele - og dette i stor stil.
Jeg springer godt nok et led over idet jeg kopiererer direkte fra FileStream til StringStream. Herefter bruger jeg så Data := StringStream.DataString til at få det hele til at være som jeg plejer at have det :) Og som sagt - det fungerer præcis sådan som jeg håbede på.
Efter at skrive dette opretter jeg et ekstra spørgsmål i denne katagori med 100 points til dig. Håber ikke det er til alt for meget besvær på denne måde.
Jeg kunne heller ikke lige greje, at jeg ikke kunne lave en StringStream.CopyFrom(FileStream) - jeg blev ved med at få en fejlmeddelelse - men nu har jeg fundet ud af det: jeg havde glemt at fjerne linien MinMemStream.Free Der kan man se, hvad der kommer ud af at arbejde for meget med VB - der kan man rask væk lave en set object = nothing, om objektet nu har været i brug eller ej.
Ja, du har ret. Alligevel får jeg en fejl, hvis jeg kører nedenstående.
procedure TForm1.Button1Click(Sender: TObject); var MinFil:TFileStream; var MinMemStream:TMemoryStream; var MinStringStream:TStringStream; var streng:string;
begin MinFil:=TFileStream.Create('c:\autoexec.bat',fmOpenRead); MinStringStream:=TStringStream.Create(streng); MinStringStream.CopyFrom(MinFil,MinFil.Size); MinStringStream.Free; MinMemStream.Free; MinFil.Free; end;
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.