|
Online
Registriert seit: 11. Okt 2003 Ort: Elbflorenz 44.339 Beiträge Delphi 12 Athens |
#10
OK, das wäre och noch 'ne Möglichkeit ... hast'e da inzwischen schon was zusammen?
hier mal meine Klasse. - ist bisher aber noch nicht getestet worden (nur im Kopf entstanden ... ich hoff mal da sind keine großen Denkfehler drin) - aber der Compiler meckert schonmal nicht ![]() Overhead wäre hierbei "nur" der aktuell geladene Block, allerdings würde natürlich beim Speichern eines Blockes eventuell der gesamte nachfolgende Teil verschoben werden.
Delphi-Quellcode:
.
Type TPartialTextfile = Class Private _FileName: String; _FileHandle: THandle; _FileSize, _Start: Int64; _OrgLen: Integer; _Part: TStringList; Function _FindNextLineBreak(Const i: Int64): Integer; Public Constructor Create; Destructor Destroy; Override; Property FileName: String Read _FileName; Property FileSize: Int64 Read _FileSize; Property Start: Int64 Read _Start; Property OrgLen: Integer Read _OrgLen; Property Part: TStringList Read _Part; Function Open (Const FileName: String): Boolean; Function LoadPart (Const Pos: Int64; MinLen: Integer): Boolean; Overload; Function LoadPart ( {next part} MinLen: Integer): Boolean; Overload; Function LoadPartLi(Const Pos: Int64; Lines: Integer): Boolean; Overload; Function LoadPartLi( {next part} Lines: Integer): Boolean; Overload; Function SavePart: Boolean; Procedure Close; End; Function TPartialTextfile._FindNextLineBreak(Const i: Int64): Integer; Var B: Array[0..65535] of Char; i2: LARGE_INTEGER; W, W2: Cardinal; Begin Result := 0; Repeat i2.QuadPart := i + Result; i2.LowPart := SetFilePointer(_FileHandle, i2.LowPart, @i2.HighPart, FILE_BEGIN); If i2.QuadPart <> i + Result Then Exit; ReadFile(_FileHandle, B, SizeOf(B), W, nil); If (W <> SizeOf(B)) and (W <> _FileSize - i - Result) Then Exit; W2 := 0; While W2 < W do Begin Inc(W2); Case B[W2 - 1] of #0, #10: Break; #13: Begin If W2 > W Then Begin i2.QuadPart := i + Result + W2; i2.LowPart := SetFilePointer(_FileHandle, i2.LowPart, @i2.HighPart, FILE_BEGIN); If i2.QuadPart = i + Result + W2 Then Begin ReadFile(_FileHandle, B, 1, W, nil); If (W = 1) and (B[0] = #10) Then Inc(W2); End; End Else If B[W2] = #10 Then Inc(W2); Break; End; End; End; Inc(Result, W2); Until W < SizeOf(B); End; Constructor TPartialTextfile.Create; Begin _FileHandle := INVALID_HANDLE_VALUE; _Part := TStringList.Create; End; Destructor TPartialTextfile.Destroy; Begin _Part.Free; End; Function TPartialTextfile.Open(Const FileName: String): Boolean; Var i64: LARGE_INTEGER; Begin If _FileHandle <> INVALID_HANDLE_VALUE Then Close; _FileHandle := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0); If _FileHandle <> INVALID_HANDLE_VALUE Then Begin i64.LowPart := GetFileSize(_FileHandle, @i64.HighPart); _FileName := FileName; _FileSize := i64.QuadPart; Result := True; End Else Result := False; End; Function TPartialTextfile.LoadPart(Const Pos: Int64; MinLen: Integer): Boolean; Var S: String; W: Cardinal; i: LARGE_INTEGER; Begin Result := False; If (_FileHandle = INVALID_HANDLE_VALUE) or (Pos > _FileSize) or (MinLen <= 0) Then Exit; Try SetLength(S, _FindNextLineBreak(Pos + MinLen)); Except Exit; End; i.QuadPart := Pos; i.LowPart := SetFilePointer(_FileHandle, i.LowPart, @i.HighPart, FILE_BEGIN); If i.QuadPart <> Pos Then Exit; ReadFile(_FileHandle, S[1], Length(S), W, nil); If Length(S) <> Integer(W) Then Exit; Try _Start := Pos; _OrgLen := Length(S); _Part.Text := S; Except _OrgLen := 0; _Part.Clear; Exit; End; Result := True; End; Function TPartialTextfile.LoadPart(MinLen: Integer): Boolean; Begin Result := LoadPartLi(_Start + _OrgLen, MinLen); End; Function TPartialTextfile.LoadPartLi(Const Pos: Int64; Lines: Integer): Boolean; Var S: String; W: Cardinal; i: LARGE_INTEGER; Begin Result := False; If (_FileHandle = INVALID_HANDLE_VALUE) or (Pos > _FileSize) or (Lines <= 0) Then Exit; W := 0; While Lines > 0 do Begin Inc(W, _FindNextLineBreak(Pos + W)); If Integer(W) < 0 Then Exit; Dec(Lines); End; Try SetLength(S, W); Except Exit; End; i.QuadPart := Pos; i.LowPart := SetFilePointer(_FileHandle, i.LowPart, @i.HighPart, FILE_BEGIN); If i.QuadPart <> Pos Then Exit; ReadFile(_FileHandle, S[1], Length(S), W, nil); If Length(S) <> Integer(W) Then Exit; Try _Start := Pos; _OrgLen := Length(S); _Part.Text := S; Except _OrgLen := 0; _Part.Clear; Exit; End; Result := True; End; Function TPartialTextfile.LoadPartLi(Lines: Integer): Boolean; Begin Result := LoadPartLi(_Start + _OrgLen, Lines); End; Function TPartialTextfile.SavePart: Boolean; Var S: String; W, W2: Cardinal; B: Array[0..65535] of Char; i, i2: LARGE_INTEGER; i3: Integer; Begin Result := False; If _FileHandle = INVALID_HANDLE_VALUE Then Exit; Try S := _Part.Text; Except Exit; End; i3 := _OrgLen - Length(S); If i3 > 0 Then Begin i.QuadPart := _Start + _OrgLen; While i.QuadPart < _FileSize do Begin i2.QuadPart := i.QuadPart; i2.LowPart := SetFilePointer(_FileHandle, i2.LowPart, @i2.HighPart, FILE_BEGIN); If i2.QuadPart <> i.QuadPart Then Exit; ReadFile(_FileHandle, B, SizeOf(B), W, nil); If (W <> SizeOf(B)) and (W <> _FileSize - i.QuadPart) Then Exit; W2 := W; i2.QuadPart := i.QuadPart - i3; i2.LowPart := SetFilePointer(_FileHandle, i2.LowPart, @i2.HighPart, FILE_BEGIN); If i2.QuadPart <> i.QuadPart - i3 Then Exit; WriteFile(_FileHandle, B, W2, W, nil); If W <> W2 Then Exit; Inc(i.QuadPart, SizeOf(B)); End; End Else If i3 < 0 Then Begin i3 := -i3; i.QuadPart := _Start + _OrgLen; Inc(i.QuadPart, (_FileSize - i.QuadPart) and -SizeOf(B)); While i.QuadPart >= _Start + _OrgLen do Begin i2.QuadPart := i.QuadPart; i2.LowPart := SetFilePointer(_FileHandle, i2.LowPart, @i2.HighPart, FILE_BEGIN); If i2.QuadPart <> i.QuadPart Then Exit; ReadFile(_FileHandle, B, SizeOf(B), W, nil); If (W <> SizeOf(B)) and (W <> _FileSize - i.QuadPart) Then Exit; W2 := W; i2.QuadPart := i.QuadPart + i3; i2.LowPart := SetFilePointer(_FileHandle, i2.LowPart, @i2.HighPart, FILE_BEGIN); If i2.QuadPart <> i.QuadPart + i3 Then Exit; WriteFile(_FileHandle, B, W2, W, nil); If W <> W2 Then Exit; dec(i.QuadPart, SizeOf(B)); End; End; Dec(_FileSize, i3); i.QuadPart := _FileSize; i.LowPart := SetFilePointer(_FileHandle, i.LowPart, @i.HighPart, FILE_BEGIN); If i.QuadPart = _FileSize Then SetEndOfFile(_FileHandle); i.QuadPart := _Start; i.LowPart := SetFilePointer(_FileHandle, i.LowPart, @i.HighPart, FILE_BEGIN); If i.QuadPart <> _Start Then Exit; WriteFile(_FileHandle, S[1], Length(S), W, nil); _OrgLen := Length(S); Result := Length(S) <> Integer(W); End; Procedure TPartialTextfile.Close; Begin CloseHandle(_FileHandle); _FileName := ''; _FileHandle := INVALID_HANDLE_VALUE; _FileSize := 0; _Start := 0; _OrgLen := 0; _Part.Clear; End;
Delphi-Quellcode:
[edit]
// Edit: TEdit;
// Button1: TButton; Procedure TForm1.Button1Click(Sender: TObject); Var PT: TPartialTextfile; Begin PT := TPartialTextfile.Create; PT.Open('Unit1.pas'); Memo1.Lines.Clear; Repeat PT.LoadPartLi(10); Memo1.Lines.Add(Format('*** %d, %d/%d', [PT.Start, PT.OrgLen, Length(PT.Part.Text)])); Memo1.lines.AddStrings(PT.Part); Memo1.Lines.Add(''); Until PT.Part.Text = ''; PT.Free; End; Fehler im Code behoben das Auslesen funktioniert anscheinend und auch eine kleine Testprozedur ist nun mit dabei [add] wenn du die geänderten Strings erstmal hinter dem "originalem" Dateiende in der Datei speicherst, dann würde auch einer dieser beiden Varianten für deine Idee ausreichen ... außerdem würden die dann nicht im RAM liegen, was bei vielen Änderungen in großen Dateien besser wäre.
Delphi-Quellcode:
PLine = ^TLine;
TLine = packed record Next, Prev: PLine; TextPos: Int64; TextLen: Integer; end; TLineArray = Array of Record TextPos: Int64; TextLen: Integer; end;
Ein Therapeut entspricht 1024 Gigapeut.
|
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |