Laden...

Ini-Datei-Klasse

Letzter Beitrag vor 15 Jahren 24 Posts 25.600 Views
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 🙁

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

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

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

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.

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

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 🙁

Hallo tom-essen,

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

(Das Leerzeichen vor \t nicht vergessen)

herbivore

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 🙁

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 🙁

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.

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 🙁

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 🙁

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;
        }

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 🙁

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?

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

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 🙁

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

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 🙁

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.

im konstruktor besser die filenotfoundexception werfen .-)

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

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.