| Autor |
Beitrag |
mback2k
Hält's aus hier
Beiträge: 13
|
Verfasst: Sa 06.10.07 10:02
Hallo Leute,
ich habe eine Frage zu der Unit TMemIniFile. Ich habe gesehen, dass diese auf viele Windows Funktionen zurückgreift und weiß nicht wo ich anfangen soll.
Mein Problem: Ich habe verschlüsselte Ini Dateien, um diese zu lesen, muss ich sie also zunächst entschlüsseln, öffnen und wieder verschlüsseln. Wäre es möglich dieses dreimalige öffnen der Dateien in einem einmaligen Prozess unterzubringen? Ich habe das mal versucht, in dem ich mit SetStrings und GetStrings gearbeitet habe und den verschlüsselten Inhalt mithilfe einer Explode Funktion von einem string in eine TStringListe umgewandelt habe, dies hat bei "großen" Dateien (ca. 400 Kb) jedoch viel zu lange gedauert.
Ich kenne mich mit dem Vererben von Klassen noch nicht so gut (lerne es gerade in der Schule) und wäre für jede Hilfe dankbar.
Hier mal mein aktueller Code:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| function TMethods.Hashcode(const text: string): string; var s: string; i: integer; begin s := text; for i:=1 to length(s) do s[i]:=char(120 xor ord(s[i])); result := s; end;
function TMethods.Hashcode_file(const AFileName: string): bool; var s: string; FileSize: integer; FileStream: TFileStream; begin if FileExists(AFileName) then begin FileSize := GetFileSizeEx(AFileName); SetLength(s,FileSize); FileStream := TFileStream.Create(AFileName,fmOpenReadWrite or fmShareDenyWrite); FileStream.Read(s[1],FileSize); FileStream.Seek(0,soFromBeginning); s := Hashcode(s); FileStream.Write(s[1],FileSize); FileStream.Destroy; result := true; end else result := false; end;
function TMethods.Hashcode_readIni(const AFileName: string): TMemIniFile; begin if Raw = false then Hashcode_file(AFileName); result := TMemIniFile.Create(AFileName); if Raw = false then Hashcode_file(AFileName); end; |
Gruß
mback2k
|
|
mback2k 
Hält's aus hier
Beiträge: 13
|
Verfasst: So 07.10.07 12:19
Sorry für den bump, aber kennt sich niemand mit der IniFiles Unit aus?
|
|
Gausi
      
Beiträge: 8554
Erhaltene Danke: 481
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: So 07.10.07 12:55
Ich würde das in etwa so lösen: Die verschlüsselte Datei in einen Stream laden und in einen anderen entschlüsseln. In diesem Stream sollte dann "normaler INI-Text" stehen. Dann diese Stringliste aus dem Stream laden und dem MemInifile-Objekt zuweisen. Das sollte auch recht fix gehen.
Nebenbei: Inifiles sind nicht für große Datenmengen gedacht - 400kb sind eigentlich zuviel für sowas. Da wäre evtl. ein ganz anderes Speicherkonzept angebracht.
_________________ We are, we were and will not be.
|
|
TheUnknown
      
Beiträge: 334
|
Verfasst: So 07.10.07 20:48
Gausi hat folgendes geschrieben: | Ich würde das in etwa so lösen: Die verschlüsselte Datei in einen Stream laden und in einen anderen entschlüsseln. In diesem Stream sollte dann "normaler INI-Text" stehen. Dann diese Stringliste aus dem Stream laden und dem MemInifile-Objekt zuweisen. Das sollte auch recht fix gehen.
Nebenbei: Inifiles sind nicht für große Datenmengen gedacht - 400kb sind eigentlich zuviel für sowas. Da wäre evtl. ein ganz anderes Speicherkonzept angebracht. |
Richtig. Normalerweise spinnt der INI-Zugriff, wenn die Datei über 64Kb geht. Wenn Du unbedingt bei INIs bleiben willst, empfehle ich Dir einen Blick auf BigINI (einfach googlen).
|
|
mback2k 
Hält's aus hier
Beiträge: 13
|
Verfasst: Mo 08.10.07 20:36
Vielen Dank für diese Informationen. Ich werde mich morgen Nachmittag nochmal damit auseinandersetzen.
Gruß
mback2k
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 08.10.07 20:46
Moin!
TheUnknown hat folgendes geschrieben: | | Normalerweise spinnt der INI-Zugriff, wenn die Datei über 64Kb geht. |
Das ist für TIniFilekorrekt, AFAIK hat TMemIniFilediese Beschränkung allerdings nicht, da es auch einer TStringListbasiert. Und die wiederum hat die praktischen Methoden .LoadFromStreamund .SaveToStream, mit denen sich Gausis Vorschlag gut umsetzen ließe.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
mback2k 
Hält's aus hier
Beiträge: 13
|
Verfasst: Di 09.10.07 14:32
Narses hat folgendes geschrieben: | Das ist für TIniFilekorrekt, AFAIK hat TMemIniFilediese Beschränkung allerdings nicht, da es auch einer TStringListbasiert. Und die wiederum hat die praktischen Methoden .LoadFromStreamund .SaveToStream, mit denen sich Gausis Vorschlag gut umsetzen ließe.  |
Genau dies würde ich ja gerne umsetzen, jedoch benötigt der Constructor von TMemIniFile einen Dateinamen und öffnet die Datei direkt, also würde ich nie unterbinden können, dass die Datei 2mal geöffnet wird, ohne das ich den Constructor abänder, oder?
Wenn ich mir so die Deklaration von TMemIniFile anschaue, stelle ich außerdem fest, dass eben jene StringList in der privaten Variable FSections gespeichert ist, von wo sie mir relativ wenig nützt, oder?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| TMemIniFile = class(TCustomIniFile) private FSections: TStringList; function AddSection(const Section: string): TStrings; function GetCaseSensitive: Boolean; procedure LoadValues; procedure SetCaseSensitive(Value: Boolean); public constructor Create(const FileName: string); destructor Destroy; override; procedure Clear; procedure DeleteKey(const Section, Ident: String); override; procedure EraseSection(const Section: string); override; procedure GetStrings(List: TStrings); procedure ReadSection(const Section: string; Strings: TStrings); override; procedure ReadSections(Strings: TStrings); override; procedure ReadSectionValues(const Section: string; Strings: TStrings); override; function ReadString(const Section, Ident, Default: string): string; override; procedure Rename(const FileName: string; Reload: Boolean); procedure SetStrings(List: TStrings); procedure UpdateFile; override; procedure WriteString(const Section, Ident, Value: String); override; property CaseSensitive: Boolean read GetCaseSensitive write SetCaseSensitive; end; |
Weiteres Problem: Ich lade die verschlüsselten Dateien ja von einem Webserver, der diese generiert. Die PHP Funktionen verschlüsseln eben auch die Zeilenumbrüche und somit kann ich die TStringList Variante auch vergessen, oder?
Irgendwie blick ich da nicht durch
Gruß
mback2k
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 09.10.07 16:12
Moin!
mback2k hat folgendes geschrieben: | | Genau dies würde ich ja gerne umsetzen, jedoch benötigt der Constructor von TMemIniFile einen Dateinamen und öffnet die Datei direkt, also würde ich nie unterbinden können, dass die Datei 2mal geöffnet wird, ohne das ich den Constructor abänder, oder? |
Ich hab mal grad in den VCL-Source (D7pro) geschaut und sehe da IMHO folgende Möglichkeit (ungetestet):
Du erzeugst die Klasseninstanz mit einem Leerstring als Dateiname, machst eine temporäre Stringliste auf und holst da (wie auch immer) die INI-Daten (unverschlüsselt) rein (hier ist also der Entschlüsselungsansatzpunkt!), dann nimmst du .SetStrings(tempSL)von TMemIniFile, um die Daten in die INI-Klasse zu schieben.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
mback2k 
Hält's aus hier
Beiträge: 13
|
Verfasst: Do 11.10.07 17:50
Vielen Dank!  Ich habe mein Problem jetzt folgendermaßen gelöst:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70:
| unit mHashIniFile;
interface
uses Windows, SysUtils, Variants, Classes, IniFiles, mMethods;
type THashIniFile = class(TMemIniFile) private HFileName: string; public constructor Create(const FileName: string); procedure UpdateFile; override; end;
implementation
constructor THashIniFile.Create(const FileName: string); var FileStrings, FileTemp: string; FileSize, FilePosition: integer; FileStream: TFileStream; FileList: TStringList; begin HFileName := FileName; FileSize := Methods.GetFileSizeEx(FileName); SetLength(FileStrings,FileSize); FileStream := TFileStream.Create(FileName,fmOpenRead or fmShareDenyWrite); FileStream.Read(FileStrings[1],FileSize); FileStream.Seek(0,soFromBeginning); FileStrings := Methods.Hashcode(FileStrings); FileStream.Free; FileList := TStringList.Create; FileTemp := ''; for FilePosition := 1 to Length(FileStrings) do begin FileTemp := FileTemp + FileStrings[FilePosition]; if FileStrings[FilePosition] = chr(10) then begin FileList.Append(FileTemp); FileTemp := ''; end; end; inherited Create(''); inherited SetStrings(FileList); FileList.Free; end;
procedure THashIniFile.UpdateFile; var FileStrings: string; FilePosition: integer; FileList: TStringList; begin FileList := TStringList.Create; try GetStrings(FileList); for FilePosition := 0 to FileList.Count-1 do FileStrings := FileStrings + FileList[FilePosition] + chr(10); FileStrings := Methods.Hashcode(FileStrings); FileList.Clear; FileList.Append(FileStrings); FileList.SaveToFile(HFileName); finally FileList.Free; end; end;
end. |
|
|
|