logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[DELPHI] Jak poprawnie odczytać dane z pliku .INI?

blue_17 08 Maj 2010 18:18 4773 28
REKLAMA
  • #1 8051649
    blue_17
    Poziom 32  
    Posty: 2414
    Pomógł: 172
    Ocena: 472
    Witam

    Mam następujący problem ustawienia programu zapisuje do pliku .ini i wszystko jest w porządku nie mam z tym problemów.

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
       var
       INI : TINIFile;
    begin
        i ni:=TINIFile.Create(ExtractFilePath(Application.ExeName)+'\system.ini');
      try
          // zapisanie ustawienia polaczenia
          INI.WriteString('Main1', 'login', form2.Edit1.Text);
            INI.WriteString('Main1', 'Database name', form2.Edit4.Text);
              INI.WriteString('Main1', 'Host name', form2.Edit5.Text);
                // zapisanie ustawim e-maila
                INI.WriteString('Main2', 'serwer', form7.Edit1.Text);
                  INI.WriteString('Main2', 'login', form7.Edit3.Text);
       finally
                  INI.Free;    // uwolnij plik
          begin
                   INI := TINIFile.Create('Sys.ini');
           try
                    INI.WriteString('Main1', '1', form7.Edit4.Text);
                     INI.WriteString('Main2', '2', form2.Edit2.Text);
          finally
                      INI.Free;
          end;
        end;
      end;
    end;
    
    end.
    
    


    Jeśli chodzi o ładowanie ustawień z pliku nie mogę tego wykombinować,
    próbowałem 4 sposobów i zawsze próba kończyła się nieudanie :|
  • REKLAMA
  • #2 8051656
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    Jak się nie stosuje:
    1. Formatowania,
    2. Kropek i innych znaków interpunkcyjnych,
    3. Głowy,
    To:
    1. Nie widać stanu obecnego,
    2. Nie rozumie się problemu i nie wiadomo, co jest jego przyczyną
    3. Nie dostaje się odpowiedzi.

    -------------

    Po edycji - te wcięcia wcale nie poprawiły czytelności.
    Wciąż nie wiem, jak próbujesz czytać plik, bo z tego co zrozumiałem, nie udaje Ci się to.

    Dodano po 10 [minuty]:

    No napisz, jakich to sposobów czterech próbowałeś. I, błagam, zapoznaj się z tym, czym jest zdanie i jakie zasady ortografii i interpunkcji obowiązują przy zapisie zdania, gdyż potok słów jest zupełnie nieprzyswajalny.
  • REKLAMA
  • #3 8051687
    blue_17
    Poziom 32  
    Posty: 2414
    Pomógł: 172
    Ocena: 472
    Dziękuj należy mi się bo może teraz faktycznie jest to czytelne ale tylko dla mnie

    W taki sposób to zapisuję

    //odczyt
    procedure TForm1.FormCreate(Sender: TObject);
    var
       ini: TINIFile;
    begin
        ini := TINIFile.Create(ExtractFilePath(Application.ExeName) + 'res.ini');
          try
           CheckBox1.Checked := ini.readbool('Rozdzielczosc','maksymalna',false);
          finally
        ini.free;
      end;
    end;
    
    //Zapis
    procedure TForm1.Button1Click(Sender: TObject);
     Var
        ini: TINIFile;
    begin
         ini := TINIFile.Create(ExtractFilePath(Application.ExeName) + 'res.ini');
          try
           ini.WriteBool('Rozdzielczosc', 'maksymalna', CheckBox1.Checked);
          finally
         ini.free;
       end;
    end;


    Oto kod odczytu który jest na razie końcowym wynikiem moich działań, niestety nie działa tak jak bym tego chciał :|


    procedure TForm1.FormCreate(Sender: TObject);
    var
    INI : TINIFile;              // zdefiniowanie zmienneych
    login : string;
    
    
    begin
        if not FileExists('System.ini') then
      begin
         ShowMessage ('Proszę uzupełnić parametry połączenia');
         try
           INI := TINIFile.Create('System.ini');
          finally
             INI.Free;
    
               begin
            if FileExists('System.ini') then
         ini:=TINIFile.Create(ExtractFilePath(Application.ExeName)+'\System.ini');
        try
       // i napewno w tym miejscu wyskakuje mi blad :(
          Form2.Edit1.Text := ini.ReadString('Main1','login','');
    
          finally
            INI.Free;
          end;
        end;
      end;
     end;
    end;
    
  • #4 8051700
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    I problem brzmi? Niezależnie od zapisu w pliku zawsze podczas odczytu dostajesz identyczną wartość, czy tak?
    BTW (z widocznymi znakami specjalnymi)
    begin
    →//cośtam
    →try
    →→//cośtam
    →finally
    →→//cośtam
    →end;
    end;
  • #6 8052102
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    W swoim kodzie masz niekonsystencę ścieżki do pliku... raz odwołujesz się poprzez podanie tylko nazwy, a raz z podaniem ścieżki wyciągniętej z exeka aplikacji.

    Poza tym:

    Cytat:
    ini:=TINIFile.Create(ExtractFilePath(Application.ExeName)+'\System.ini');


    Po pierwsze, jeśli chcesz użyć ukośnika, to musisz dać ich DWA, a po drugie, AFAIR funkcja ExtractFilePath zwraca stringa już z tym ukośnikiem właśnie.
  • REKLAMA
  • #7 8052104
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    Po pierwsze, to utworzenie obiektu klasy TIniFile zawsze powoduje założenie pliku. Po drugie pierwszy try w drugim kodzie jest zupełnie źle zlokalizowany (pomijając fakt zupełnej zbyteczności tego kodu). Po trzecie cały kod wywołujesz tylko, gdy plik nie istnieje. Po czwarte dla INIFile definiujesz ścieżkę, a dla sprawdzenia istnienia opierasz się o katalog roboczy. Po piąte Po raz drugi tworzysz obiekt klasy tylko, gdy plik istnieje, a próbujesz go wykorzystać zawsze. Po szóste - masz wcześniej poprawny kod, a później tworzysz jakieś udziwnienia. Ten wcześniejszy też nie działa? Po siódme - wiesz o istnieniu czegoś takiego, jak debuger i pracy krokowej?

    Dodano po 49 [sekundy]:

    utak3r napisał:
    Po pierwsze, jeśli chcesz użyć ukośnika, to musisz dać ich DWA
    Utak3r - to nie C ani WinAPI! Nie opowiadaj bzdur!
  • Pomocny post
    #8 8052331
    lanky
    Poziom 17  
    Posty: 149
    Pomógł: 27
    Ocena: 7
    słyszałeś o else ?

    
    var
    INI : TINIFile;   
    begin
    if not FileExists('System.ini') then   // gdy nie ma to "zapisz"
    begin
      INI := TINIFile.Create(ExtractFilePath(Application.EXEName) + 'System.ini');
      INI.WriteString('Pozycja1', 'Pozycja2', 'abc');
      INI.Free;
    end else
    
    if FileExists('System.ini') then   // w przeciwnym wypadku "wczytaj"
    begin
      INI:=TINIFile.Create(ExtractFilePath(Application.ExeName)+'\System.ini');
      Form1.Edit1.Text := INI.ReadString('Pozycja1','Pozycja2','');
      INI.Free;
    end;
    
  • #9 8052385
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    lanky napisał:
    słyszałeś o else ?

    
    if not FileExists('System.ini') then   // gdy nie ma to "zapisz"
    .........
    end else
    if FileExists('System.ini') then   // w przeciwnym wypadku "wczytaj"
    ................


    a po co ten if w else? No, chyba że po to, że w trakcie przeskakiwania między gałęziami kodu sytuacja na dysku się zmieni.... ;)
  • #10 8052390
    blue_17
    Poziom 32  
    Posty: 2414
    Pomógł: 172
    Ocena: 472
    Dobrze ale to nie robi tego co ja chcę

    Na początku sprawdzam czy plik istnieje jeśli nie to tylko wyświetlam komunikat "proszę uzupełnić parametry połączenia"

    Jeśli jest plik to ładuje z niego dane.

    nic więcej przy otwieraniu formy nie chcę robić

    Przy zamykaniu zapisuje dane co mam już opanowane a więc kolego prawie oto mi chodzi jednakże nie do końca.
  • #11 8052394
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    lanky - i po co ten else w Twoim kodzie, skro za nim robisz przeciwnego IFa? A poza tym raczej się nie zdarza, aby tak kod miał działać.
  • #12 8052398
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    Dżyszla napisał:
    utak3r napisał:
    Po pierwsze, jeśli chcesz użyć ukośnika, to musisz dać ich DWA
    Utak3r - to nie C ani WinAPI! Nie opowiadaj bzdur!


    Zgadza się, masz rację (rzadko piszę w Delphi), co nie zmienia faktu, żeby sprawdził to, co napisałem tam dalej (sprawdził, bo piszę z pamięci).
  • #15 8052409
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    urak3r - zarzuciłem to, co jest nieprawdą, nie skomentowałem tego, co prawdą jest ;)

    Dodano po 52 [sekundy]:

    Jak to się nie da odpalić aplikacji? :o
  • #16 8052413
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    A co z tym debuggerem? Na czym się wykłada?..... to powinno być pierwsze, co robisz, jak są problemy. A jak na razie, to obstawiam, że nawet nie wiesz, co to znaczy.
  • #17 8052435
    blue_17
    Poziom 32  
    Posty: 2414
    Pomógł: 172
    Ocena: 472
    Trzeba zwrócić honor i uderzyć się w pierś kolega lanky podał działający kod.

    kod nie zadziałał w pierwszej chwili bo wpisałem zamiast

     Form1.Edit1.Text := INI.ReadString('main1','login','');



     Form2.Edit1.Text := INI.ReadString('main1','login','');


    Ale chciałbym aby działało z drugą wersją bo tak mam w aplikacji
  • REKLAMA
  • #18 8052818
    lanky
    Poziom 17  
    Posty: 149
    Pomógł: 27
    Ocena: 7
    Cytat:

    lanky - i po co ten else w Twoim kodzie, skro za nim robisz przeciwnego IFa? A poza tym raczej się nie zdarza, aby tak kod miał działać.

    sorry to przez Ctrl C i V, chciałem być szybszy niż lucky luke xD

    A jeśli chodzi o błędy blue_17 i masz z tym większy problem to proponuję Ci się zapoznać z F7 i F8
  • #20 8052894
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    Błędu... co robi? Po zmianie parametru wyskakuje "według mnie powinno chodzić..."?

    I opisz jaśniej, co chcesz osiągnąć i jak wygląda struktura aplikacji, bo nic nie wiadomo. Piszesz o odczycie z INI a problem zupełnie go nie dotyczy najwyraźniej.
  • #21 8052928
    blue_17
    Poziom 32  
    Posty: 2414
    Pomógł: 172
    Ocena: 472
    Chcę aby wartość pojawiająca się w edice1 na formie1 pojawiała się w edicie1 na formie2

    Kiedy uruchamiam aplikację wyświetla się główne okno form1 wybieram z popmenu ustawienia i wyświetla mi się forma 2.
  • #22 8052943
    lanky
    Poziom 17  
    Posty: 149
    Pomógł: 27
    Ocena: 7
    No bo pewnie chcesz wpierdzielić od razu tekst na forme2 która nawet nie została otworzona.
    zrób pierw:

    
    Form2.Show; // otwarcie 2 formy
    //i potem przepisz coś do Form2.Edit
    
  • #23 8053019
    blue_17
    Poziom 32  
    Posty: 2414
    Pomógł: 172
    Ocena: 472
    Przypuszczałem że może oto chodzić ale po mio edycji kodu nadal wyskakuje mi błąd

    procedure TForm1.FormCreate(Sender: TObject);
    
     var
    INI : TINIFile;
    begin
    if not FileExists('System.ini') then   // gdy nie ma to "zapisz"
    begin
    INI := TINIFile.Create('System.ini');
        INI := TINIFile.Create(ExtractFilePath(Application.EXEName) + 'System.ini');
        INI.WriteString('Pozycja1', 'Pozycja2', 'abc');
        INI.Free;
    end else
    Form2.Show;
    if FileExists('System.ini') then   // w przeciwnym wypadku "wczytaj"
    begin
      INI:=TINIFile.Create(ExtractFilePath(Application.ExeName)+'\System.ini');
      Form2.Edit1.Text := INI.ReadString('main1','login','');
      INI.Free;
    end;
    end;
    



    To może dziwne ale przy zamykaniu kiedy zapisuję do pliku nie mam aktywnej 2 formy a zapis wykonuje się prawidłowo
  • #24 8053044
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    blue_17 napisał:
    nadal wyskakuje mi błąd


    Cytując pewien film - zaraz odwiozą mnie do Tworek....
    JAKI błąd? Co z tym ch...m debuggerem??
  • #25 8053055
    blue_17
    Poziom 32  
    Posty: 2414
    Pomógł: 172
    Ocena: 472
    Doszedłem już co jest nie tak w nieodpowiednim zdarzeniu zamieściłem kod i nie mogę się odwoływać w tym zdarzeniu do form2 muszę to zamieścić w zdarzeniu OnShow :)

    Bo formy tworzone są poklei :)

    Działa dziękuje wszystkim którzy się zemną użerali a w szczególności koledze utak3r

    procedure TForm1.FormShow(Sender: TObject);
    
    var
    INI : TINIFile;
    begin
    if not FileExists('System.ini') then   // gdy nie ma to "zapisz"
    begin
    INI := TINIFile.Create('System.ini');
        INI := TINIFile.Create(ExtractFilePath(Application.EXEName) + 'System.ini');
        INI.WriteString('Pozycja1', 'Pozycja2', 'abc');
        INI.Free;
    end else
    if FileExists('System.ini') then   // w przeciwnym wypadku "wczytaj"
    begin
      INI:=TINIFile.Create(ExtractFilePath(Application.ExeName)+'\System.ini');
      Form2.Edit1.Text := INI.ReadString('main1','login','');
      INI.Free;
    
    end;
    end;
    
  • #26 8053101
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    O ile masz Form2 jako AutoCreate Form. Jeśli chcesz coś do komponentu na Form2 przypisać, to zrób to w metodzie Form2! W ten sposób kod będzie bezpiecznym niezależnie, czy stworzysz Form2 wcześniej, czy później, czy zrobisz kilka egzemplarzy, czy wywołasz dynamicznie itd.

    I dalej kod jest zbyteczny ze względu na ELSE. I w ogóle nie ma potrzeby sprawdzać istnienia pliku! (na dodatek z jakimiś sztucznymi pozycjami, których nigdy nie czytasz) Myśl trochę kopiując!

    Obejmij odczyt blokiem try..finally ponownie.

    Dodano po 4 [minuty]:

    W zupełności wystarczy taki kod (przeniesiony do Form2!):
    procedure TForm2.FormCreate(Sender: TObject);
    begin
       with TINIFile.Create(ExtractFilePath(Application.ExeName)+'System.ini') do begin
          try
             Edit1.Text:=ReadString('main1','login','');
          finally
             Free;
          end;
       end;
    end; 
  • Pomocny post
    #28 8053392
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    Będę chyba wredny w pisaniu bo dotychczasowe prośby jak widać nie przynoszą skutku powodzenia w rozumieniu tego tekstu który za chwilę napiszę nie_ma potrzeby gdyż czytanie z nieistniejącego pliku powoduje stosowanie wartości domyślnych jeśli chcesz w jakiś sposób poinformować o pierwszym uruchomieniu to wystarczy faktycznie skorzystać z funkcji FileExists i ustawić jakąś flagę (zmienną), lecz odczyt może dalej być prowadzony w dotychczasowy sposób utworzenie obiektu nie powoduje żadnych wyjątków podobnie jak nie powoduje wyjątków czytanie nieistniejących zapisów w takim pliku od tego są właśnie wartości domyślne (dane ZAWSZE mają skąd się wziąć), co odróżnia pliki INI od rejestru systemowego.

Podsumowanie tematu

✨ W dyskusji poruszono problem odczytu danych z pliku .INI w aplikacji Delphi. Użytkownik miał trudności z poprawnym wczytywaniem wartości do komponentów formularza, co prowadziło do błędów, gdy plik istniał, ale dane nie były ładowane. Uczestnicy forum wskazali na niekonsekwencje w ścieżkach do plików oraz błędy w logice kodu, sugerując poprawki, takie jak użycie bloku try..finally oraz odpowiedniego sprawdzania istnienia pliku. Ostatecznie, po kilku próbach, autor zdołał zaimplementować działający kod, który poprawnie odczytuje dane z pliku .INI i wyświetla je w formularzu.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA