Laden...

Ini-Datei-Klasse

Erstellt von tom-essen vor 16 Jahren Letzter Beitrag vor 14 Jahren 25.420 Views
tom-essen Themenstarter:in
1.818 Beiträge seit 2005
vor 16 Jahren
Ini-Datei-Klasse

Beschreibung:

Mit der hier vorliegenden Klasse kann man rel. einfach Dateien im Ini-Format erstellen/bearbeiten, da ja doch noch in vielen Fällen von anderen Programmen Daten in dieser Form gespeichert werden. Die Klasse ist noch nicht perfekt, aber ich arbeite daran. Wer will, kann natürlich gerne seinen Senf dazugeben, ich werde die Klasse dann ggf. entsprechend erweitern.

Eine Konfiguration kann entweder komplett neu mit dem Standard-Konstruktor erstellt oder von einer vorhandenen Datei eingelesen werden.

Mit getValue kann man Werte auslesen, mit setValue setzen. getCaption gibt alle Einträge eines Bereiches zurück, mit Save kann man die Änderungen speichern.
exportToXml ist erstmal nur ein Stub.

Edit: Kleine Fehler beseitigt.
Edit2: Unterstützung von Groß-/Kleinschreibung, bessere Kommentarzeichensuche (Dank an Beauty für den Tipp und Herbivore für die Umsetzung).
Edit3: Kleinen Fehler bei setValue behoben: Einfügen neuer Werte nun direkt unter der Caption-Zeile, damit neue Werte nicht versehentlich hinter auskommentierten Captions eingefügt werden.
Edit4: export2Xml() funktioniert nun, deleteValue hinzugefügt, interne Redundanzen behoben.
Edit5: getAllCaptions integriert, Dank an Johnny.
Edit6: FileName-Property angepasst. Nun werden Dateien auch dann korrekt verarbeitet, wenn der Dateiname nicht über den Konstruktor, sondern auch über die FileName-property gesetzt wird. Dank an Abt.
Edit7: Property-Namen angepasst und alles in regions gepackt.

Ich lass' den Quellcode nun mal aus dem Text raus, kann man sich ja auch über den Anhang schnell holen (sind mittlerweile immerhin über 350 Zeilen 8o).

Schlagwörter: Datei,Ini,Konfiguration,Xml,Cfg>

Nobody is perfect. I'm sad, i'm not nobody 🙁

79 Beiträge seit 2007
vor 16 Jahren

schöne Sache (-:

Habe gerade auf Wikipedia über ini-Dateien gelesen.
Da steht, daß Kommentare mit Semikolon anfangen.
Bei Dir sind Kommentare als Raute angegeben.
Vielleicht sollte man die Funktionalität auf beides erweitern.

Falls auch Leerzeichen oder Tabs vor Kommentaren unterstützt werden sollen, kann ich Dir für die if-Bedingung einen kurzen RegEx-Code schreiben. Kenne mich damit halbwegs gut aus durch Perl-Programmierung.
Ob eingerückte Kommentare in der Praxis vorkommen, weiß ich nicht. Wäre zumindest lesefreundlicher.


if (line[0].ToString() == "#") continue;// Kommentar

ändern zu


if ((line[0].ToString() == "#") || (line[0].ToString() == ";")) continue;// Kommentar

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Beauty,

Ob eingerückte Kommentare in der Praxis vorkommen, weiß ich nicht. Wäre zumindest lesefreundlicher.

soweit ich weiß, muss das Kommentarzeichen in Spalte 1 stehen, mindestens aber als erstes (Nicht-Leer-)Zeichen in der Zeile, damit es keine Konflikte gibt, wenn das Zeichen im Werten vorkommt. Ini ist ja ein sehr einfaches Format.

herbivore

D
462 Beiträge seit 2005
vor 16 Jahren

Original von Beauty
ändern zu

  
if ((line[0].ToString() == "#") || (line[0].ToString() == ";")) continue;// Kommentar  
  

und das widerrum ändern zu:


if ((line[0] == '#') || (line[0] == ';')) continue;// Kommentar

😉

mfg

79 Beiträge seit 2007
vor 16 Jahren

Mir fällt gerade auf, daß keine Ausnahmen abgefangen werden.
z.B. im Systemverzeichnis kann es beim Schreiben / Ändern einer Datei zu einer kommen.
Ich glaube es wäre sinnvoll, da was einbauen.

0
767 Beiträge seit 2005
vor 16 Jahren

da die klasse kein UI oder log hat, kann er mit der ausnahme nichts weiter machen als sie zu a) ignorieren oder b) weiterzuwerfen.

a) schlecht, weil man dann beim verwenden annehmen könnte dass alles geklappt hat, was nicht stimmt.

b) in dem fall braucht man sie gar nicht fangen.

loop:
btst #6,$bfe001
bne.s loop
rts

tom-essen Themenstarter:in
1.818 Beiträge seit 2005
vor 16 Jahren

Hallo!

@beauty:
Danke für deine Hilfe, ein entsprechender RegEx-Code wäre nett, dass mit den Leerzeichen habe ich ja bereits durch "trim()" gelöst.

@beauty & 0815Coder:
Dass mit den Ausnahmen könnte man ähnlich wie im Konstruktor regeln, die Exception kann dann im Aufruf abgefangen werden, wäre zumindest bzgl. der Fehlermeldung etwas komfortabler. Kommt mit auf die Liste 😉

Nobody is perfect. I'm sad, i'm not nobody 🙁

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo tom-essen,

if (Regex.IsMatch (line, @"^[ \t]*[#;]")) continue; // Kommentar

(Das Leerzeichen vor \t nicht vergessen)

herbivore

tom-essen Themenstarter:in
1.818 Beiträge seit 2005
vor 16 Jahren

Hallo!

Hab' den Beitrag oben entsprechend angepasst.

Habe diese Komponente natürlich zu einem bestimmten Zweck geschrieben, den ich im Thread Subversion-Repository-Konfigurator erkläre.

Nobody is perfect. I'm sad, i'm not nobody 🙁

tom-essen Themenstarter:in
1.818 Beiträge seit 2005
vor 16 Jahren
Ini-Datei-Klasse

Hallo!

Bzgl. Ini-Dateien gibt es noch einen älteren Thread, welcher mir leider erst gestern zufällig aufgefallen, als ich meinen gesucht habe 8o.

Link zum IniReader.

Vorteil dieses Readers ist sicherlich die konsequente Verwendung von RegEx.

Nobody is perfect. I'm sad, i'm not nobody 🙁

J
163 Beiträge seit 2007
vor 16 Jahren

Super Sache, habe mich bisher immer gedrückt so was zu schreiben und jetzt kommst du... mir fehlt nur noch ne Methode zu Löschen eine Eintrages/Bereiches.

tom-essen Themenstarter:in
1.818 Beiträge seit 2005
vor 16 Jahren

Hallo!

@Johnny:
Danke für die Blumen. 🙂
Bzgl. Löschen eines Eintrages gibt es alternativ die Möglichkeit, den Eintrag auszukommentieren (commentValue). Aber kommt mit auf die Liste.

Nobody is perfect. I'm sad, i'm not nobody 🙁

tom-essen Themenstarter:in
1.818 Beiträge seit 2005
vor 16 Jahren

Hallo!

Es gibt eine neue Version der Ini-Datei-Klasse:

* export2Xml funktioniert nun
* deleteValue wurde hinzugefügt
* Intern weniger redundanter Code
* Intern stärkere Verwendung von regulären Ausdrücken

Download im ersten Beitrag dieses Threads.

Nobody is perfect. I'm sad, i'm not nobody 🙁

J
163 Beiträge seit 2007
vor 16 Jahren

Habe mal eine Methode zum einlesen aller Bereiche gebraucht. Vielleicht kanns jemand gebrauchen bzw. optimieren, da meine zu Quick&Dirty ist.


        public List<string> getAllCaptions()
        {
            List<string> result = new List<string>();
            for (int i = 0; i < lines.Count; i++)
            {
                String line = lines[i].Trim();

                if (line.StartsWith("[") && line.EndsWith("]"))
                {
                    result.Add(line.Substring(1, line.Length-2));
                }
            }
            return result;
        }

tom-essen Themenstarter:in
1.818 Beiträge seit 2005
vor 16 Jahren

Hallo!

@Johnny:
Danke für die Erweiterung, ist mit ein wenig Modifikation (Reguläre Ausdrücke) in die Klasse eingebaut worden.

Download wie gehabt über den ersten Beitrag.

Nobody is perfect. I'm sad, i'm not nobody 🙁

D
15 Beiträge seit 2007
vor 15 Jahren

hallo tom!

danke für diese schöne klasse, ich verwende sie auch grad.
der grund, warum ich diesen thread rauskram ist, eine verständisfrage, bzw ein eventueller fehler.

Zeile 299
in der methode "getCaptions"

if (line.ToLower() != "[" + Caption + "]") continue;

wieso denn .ToLower() ?
wenn ich sowohl in der ini-datei als auch in meinem code case-sensitiv bin, findet er den gewünschten eintrag nicht. das kann doch nicht sinnd er sache sein, oder?

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo dennisderweber,

ich würde sagen: works as designed. 🙂

Wenn du es anders haben willst, kannst du es auch einfach anpassen. Sprich auf line und auf Caption ToLower anwenden und es an beiden Stellen lassen.

herbivore

tom-essen Themenstarter:in
1.818 Beiträge seit 2005
vor 15 Jahren

Hallo!

Idealerweise gäbe es natürlich eine boolsche Variable, welche Case-Sensitivität ein- oder ausschalten kann.

Aber mir ist damals auch einfach kein Use-Case eingefallen, wo eine Verwendung von zwei nur durch die Groß-/Kleinschreibung unterschiedenen Captions Sinn machen würde.

EDIT: Spellcheck

Nobody is perfect. I'm sad, i'm not nobody 🙁

S
49 Beiträge seit 2008
vor 15 Jahren

Hallo tom-essen,

habe da mal eine Frage.

Kann ich deine Klasse in meinem Projekt einfach so einbinden?
Oder soll ich in der Summary einen Eintrag von dir hinterlegen.
Oder iwas bei den Credits bemerken???

Wäre nett wenn du antworten könntest...

schönes Wochenende

shacknet

tom-essen Themenstarter:in
1.818 Beiträge seit 2005
vor 15 Jahren

Hallo!

Eine Erwähnung, wo die Klasse herkommt, also der Link auf diesen Thread, würde mir reichen, und dem Forum evtl. neue Besucher bescheren 😉.

Nobody is perfect. I'm sad, i'm not nobody 🙁

296 Beiträge seit 2007
vor 15 Jahren

Schöne Klasse - kann ich gut gebrauchen.
Einen kleinen Fehler hat das Ganze noch im Konstruktor:


        public IniFile(string filename) : this ()
        {
            if (!File.Exists(filename)) throw new IOException("File " + filename + "  not found");
            fileName = filename;
        }

Sollte heissen:


        public IniFile(string filename) : this ()
        {
            if (!File.Exists(filename)) throw new IOException("File " + filename + "  not found");
            FileName = filename;
        }

Sonst werden die Lines natürlich nicht geladen.

I
279 Beiträge seit 2008
vor 15 Jahren

im konstruktor besser die filenotfoundexception werfen .-)

T
60 Beiträge seit 2008
vor 14 Jahren

Hallo zusammen,

ich habe gerade einen Fehler entdeckt und eine Möglichkeit für einen BugFix angehängt.

Falls die Inidatei nachfolgende Struktur hat


[LANGUAGE]
Language=GR
Language2=UK
LanguageList=GR, UK, SP, FR, IT, CH

und ich nach getValue(Language, Language, false) suche funktioniert das ganze, wenn aber der Schlüssel Language fehlt, wird Language2 gefunden. Wenn beide Schlüssel fehlen wird die Liste der Srachen gefunden. Ist unschön.
Hier mein Bugfix-Vorschlag


private int SearchEntryLine(String Caption, String Entry, Boolean CaseSensitive)
{
	...
	for (int i = CaptionStart + 1; i < lines.Count; i++)
	{
		...
		if (Regex.IsMatch(line, @"^" + Entry + @"\s*="))
		//if (line.StartsWith(Entry)) alte fehlerhafte Variante
			return i;// Eintrag gefunden
	}
	return -1;// Eintrag nicht gefunden
}

Gruß Turmoil

W
56 Beiträge seit 2009
vor 14 Jahren

Wie erstelle ich eine Neue ini datei, bei der ich den Pfad angebe`?

MfG Iwan

Alle haben gesagt es geht nicht, dann kam einer der hat das nicht gehört und hat es gemacht.