Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#10

Re: Datein in ein program einbinden

  Alt 9. Okt 2006, 13:02
Wie gesagt, die Hilfe hilft eigentlich schon weiter.

Aber kurz ein wenig zum TIniFile (TMemInifile verhält sich an vielen Stellen analog, du arbeitest aber nur im Speicher, musst also explizit zurückschreiben).

Eine Ini-Datei ist eine reine Textdatei. Es gibt jedoch eine spezielle Formatierung, die Delphi hier für dich auto. berücksichtigt. Du hast Sektionen, Schlüssel und Werte.
Der Name einer Sektion muss eindeutig/einzigartig in der gesamten Datei sein. Eine Sektion wird durch Eckige Klammern angezeigt [Sektionsname].
Zu jeder Sektion kannst du beliebig viele Schlüssel-Wertpaare erzeugen. Hier muss der Schlüssel innerhalb einer Sektion eindeutig sein, er kann aber in z.B. in zwei verschiedenen Sektionen verwendet werden. Der Schlüssel ist eine Zeichenkette der Wert des Schlüssels auch (der kann aber auch interpretiert werden). Die Zuweisung wird durch ein = angezeigt. Grob hat also eine Ini-Datei den Aufbau

Code:
[Sektion1]
Schlüssel1=Wert1
Schlüssel2=Wert1

[Sektion2]
Schlüssel1=Wert2
Schlüssel3=Wert3
...
Der Zugriff auf eine solche Datei erfolgt in Delphi gekapselt durch die Klasse TIniFile und Nachfolger. Der Name der zu öffnenden Datei wird im Konstruktor übergeben, dabei solltest du immer mit dem absoluten Pfad arbeiten, diesen aber auch erst zur Laufzeit ermitteln. Es gibt zu jedem Programm immer ein aktuelles Arbeitsverzeichnis. Gibts du relative Pfade an (z.B. nur DeineIni.ini), so die Datei im aktuellen Arbeitsverzeichnis gespeichert oder gesucht. Bei der Auswahl durch einen Lade/Speichern Dialog eines Verzeichnis änderst du (u.A.) dieses Verzeichnis, hier könntest du dann Probleme bekommen, wenn du den Pfad relativ angibst. Besser ist es, wenn du weißt wie der Pfad zur Laufzeit ermittelt werden kann. Im einfachsten Fall hast du ein Verzeichnis, dessen Position relativ zur gestarteten Exe du kennst (im einfachsten Fall liegt beides im gleichen Ordner). Den Pfad zu deiner Exe ermittelst du einfach mit ExtractFilePath(ParamStr(0)). Der absolute Pfad wäre dann (ini im Verzeichnis der Exe): ExtractFilePath + 'DeineIni.ini'

Hast du nun ein TIniFile Objekt erzeugt, kannst du wahlfrei auf einzelne Werte zugreifen. Ein Wert kann immer durch die Sektion und den Schlüssel ermittelt werden. Ein Problem dass du bei deinem Projekt haben kannst ist, dass du nicht alle Sektionen kennst. Ich gehe hier mal einfach davon aus, dass du für jeden Künstler eine Sektion anlegst, jeder Song ist dann ein Schlüssel, jeder Songtext ist der Wert.
Liest du also die Ini ein, hast du eine bestimmte Anzahl von dir noch unbekannten Künstlern. Du musst also erstmal schauen, welche Sektionen / Künstler existieren in der Datei. Dazu gibt es die Funktion ReadSections. Hier werden alle Sektionen ausgelesen und in ein TStrings Objekt geschrieben. TStrings ist ein abstrakter Datentyp, du kannst hier z.B. eine TStringList nehmen. Der Name TStringList sagt dann auch schon deutlicher was du hier verwendest, es handelt sich um eine Liste von Strings. Wie man mit einer TStringList arbeitet ist nicht weiter kompliziert, du legst sie mit Create an und übergibst diese Instanz an die Methode ReadSections. Danach kannst du mit der Eigenschaft Count schauen wie viele Strings in der StringList stehen und wie bei einem Array mittels [index] auf den String an der Stelle [index] zugreifen.
Der nächste Schritt wäre es nun, dass du zu jedem Künstler seine Songs einliest. Auch hier hast wieder eine unbekannte Anzahl von Elementen, auch hier kannst du aber auf die Kapselung zurückgreifen. Für jede Sektion kannst du einfach ReadSection aufrufen. Readsection selbst liest einfach die Schlüssel in der Sektion ein und schreibt diese wiederum in ein TStrings Objekt. Nun hast du die Sektion (Künstler), alle Schlüssel (Titel) und kannst zu jedem Schlüssel dieser Sektion den Wert einlesen, dazu wird dann einfach readString verwendet. Hier findest du aber auch Alternativen, die für dich bereits eine Typumwandlung durchführen (z.B. readInteger oder readBool).
Das wäre schon der ganze Weg für das Lesen.

Delphi-Quellcode:
var iniFile : TIniFile;
    interpreten : TStringlist;
    songs : TStringList;
    text : String;
    i : Integer;
    j : Integer;
begin
  iniFile := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'WasAuchImmer.ini');
  
  try
    interpreten := TStringList.Create;
    songs := TStringList.Create;

    try
      iniFile.ReadSections(interpreten);
      
      if interpreten.Count > 0 then
      begin
        for i := 0 to interpreten.Count - 1 do
        begin
          songs.Clear;
          
          iniFile.ReadSection(interpreten[i], songs);
          
          if songs.Count > 0 then
          begin
            for j := 0 to songs.Count - 1 do
            begin
              text := iniFile.ReadString(interpreten[i], songs[j], '');
              
              // jetzt enthält Text den gespeicherten Wert.
              // interpreten[i] zeigt den aktuellen Interpreten an
              // songs[j] enthält den Songtitel
            end; // for j := 0 to songs.Count - 1
          end; // if songs.Count > 0
        end; // for i := 0 to interpreten.Count - 1
      end; // if interpreten.Count > 0
    finally
      songs.Free;
      interpreten.Free;
    end;
  finally
    iniFile.Free;
  end;
So, jetzt hast du das ganze als Codebeispiel. Allerdings ist das so kein schöner Code! Du solltest hier lieber mehr als eine Methode verwenden (z.B. das Lesen eines Songs oder aller Songs des Interpreten trennen).
Jedenfalls ist das schon die komplette Logik beim Lesen. Schreiben ist noch viel einfacher, du verwendest einfach die WriteString Methode von TIniFile. Wenn du mit TMemIniFile arbeitest, wird die Datei erst beim Aufruf von Update gespeichert.

Gruß Der Unwissende