Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: AlexLazarus - Ottobre 24, 2022, 09:50:17 am

Titolo: Come aprire e leggere un banale file di testo? [RISOLTO]
Inserito da: AlexLazarus - Ottobre 24, 2022, 09:50:17 am
Purtroppo non riesco a trovare sul web un esempio concreto (cioè dall'inizio alla fine) sull'apertura / lettura di un file.

Problema:

Aprire un banale file di testo e trasferire in una ListBox il suo contenuto.

1) Come rendere visibile (e ovviamente selezionare directory e file )la classica finestra di dialogo OpenDialog?
2) Come aprire correttamente un file per esaminare il contenuto?

1a) Come si può notare  dai due screenshot, riesco a leggere il file, ma sono costretto a farlo in maniera diretta (cfr: NomeFile:= 'D:\IlMioFile.txt') dato che non sono riuscito a visualizzare la finestra di dialogo.
2a) Evidentemente manca qualcosa prima / dopo: FileOpen('D:\IlMioFile.txt',1)

Nonostante la brevità del programma, allego qui di seguito il sorgente (ovviamente stravolto a causa della traduzione automatica in italiano 😉) .

Grazie a chi vorrà aiutarmi, anche indicandomi semplicemente un link ove trovare un esempio semplice e COMPLETO (quelli che ho trovato sono indicazioni generiche, non soddisfacenti).



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


implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);

Var NomeFile, Elemento: string;
Var F: system.Text;

begin
  NomeFile:= 'D:\IlMioFile.txt' ;

  if FileExists(NomeFile) then
      Begin
        ShowMessage('Il file: ' + NomeFile + ' esiste');
        end
        else if  FileExists(NomeFile) =False Then
        ShowMessage('Il file: ' + NomeFile + ' NON esiste');

AssignFile(F,'D:\IlMioFile.txt');
reset (F);
FileOpen('D:\IlMioFile.txt',1);
While Not EOF(F) Do ReadLn(F, Elemento);
writeln(1,Elemento);
end;

end.
Titolo: Re:Come aprire e leggere un banale file di testo?
Inserito da: nomorelogic - Ottobre 24, 2022, 10:13:45 am
Ciao
per la lettura di un file puoi evitare l'approccio classico reset/readln a meno che tu non si a costretto per fare elaborazioni particolari

Puoi usare ad esempio TStringList (che discende da TStrings) e con una unica istruzione leggi tutto il file
ad esempio

Codice: [Seleziona]
procedure Leggi;
var sl: TStringList;
begin
   sl:=TStringList.Create;
   try
      sl.LoadFromFile('nomefile.txt');
      ShowMessage('righe lette: ' + IntToStr(sl.Count));
   finally
      sl.Free;
   end;
end;

per popolare una listbox, basta far caso al fatto che la proprietà Items discende anch'essa da TStrings
e quindi:

Codice: [Seleziona]
...
ListBox1.Items.LoadFromFile('nomefile.txt');
...

Ciao
nomorelogic
Titolo: Re:Come aprire e leggere un banale file di testo?
Inserito da: AlexLazarus - Ottobre 24, 2022, 10:51:56 am
Anzitutto, GRAZIE MILLE per la rapida risposta. Funziona tutto, come si può notare nello screenshot.😉
Però non hai detto come fare per visualizzare la finestra di dialogo OpenDialog.
Sul web avevo trovato questa manciata di righe da mettere prima dell'apertura del file, ma non succede niente:

begin
   OpenDialog1.DoShow;
    with OpenDialog1 do begin
      DefaultExt:= '.txt';
      Filter:= 'File txt (*.txt)|*.txt';
      OpenDialog1.Title:='Seleziona il file';
      OpenDialog1.Options:=[ofEnableSizing,ofViewDetail,ofReadOnly];

P.S. E per creare un file di testo in cui trasferire il contenuto di una ListBox? (Chiedo troppo, lo so...).
Titolo: Re:Come aprire e leggere un banale file di testo?
Inserito da: DragoRosso - Ottobre 24, 2022, 10:58:18 am
Purtroppo non riesco a trovare sul web un esempio concreto (cioè dall'inizio alla fine) sull'apertura / lettura di un file.

Problema:

Aprire un banale file di testo e trasferire in una ListBox il suo contenuto.

1) Come rendere visibile (e ovviamente selezionare directory e file )la classica finestra di dialogo OpenDialog?
2) Come aprire correttamente un file per esaminare il contenuto?

1a) Come si può notare  dai due screenshot, riesco a leggere il file, ma sono costretto a farlo in maniera diretta (cfr: NomeFile:= 'D:\IlMioFile.txt') dato che non sono riuscito a visualizzare la finestra di dialogo.
2a) Evidentemente manca qualcosa prima / dopo: FileOpen('D:\IlMioFile.txt',1)

Nonostante la brevità del programma, allego qui di seguito il sorgente (ovviamente stravolto a causa della traduzione automatica in italiano 😉) .

Grazie a chi vorrà aiutarmi, anche indicandomi semplicemente un link ove trovare un esempio semplice e COMPLETO (quelli che ho trovato sono indicazioni generiche, non soddisfacenti).

Per visualizzare la finestra di dialogo, esegui la funzione "Execute" del componente:

Codice: [Seleziona]
if OpenDialog1.Execute then
  begin
      //Qui esegui qualcosa se l'utente ha selezionato un file
      //Nella proprietà OpenDialog1.FILES c'è l'elenco dei file che l'utente ha selezionato.
  end
else
  begin
    //Qui esegui qualcosa se l'utente ha premuto il tasto "annulla"
  end;

Per la lettura invece segui il consiglio di @nomorelogic.

P.S.: Non usare il "DoShow", è chiamato internamente dalla "Execute". Quel metodo, a mio personalissimo parere, non dovrebbe essere esposto pubblicamente. Ripeto, mio personalissimo parere.

Ciao
Titolo: Re:Come aprire e leggere un banale file di testo?
Inserito da: DragoRosso - Ottobre 24, 2022, 11:11:10 am
P.S. E per creare un file di testo in cui trasferire il contenuto di una ListBox? (Chiedo troppo, lo so...).

Usa il componente "TSaveDialog" (similmente a quanto fai con "TOpenDialog") e poi usi la funzione:

Codice: [Seleziona]
ListBox1.Items.SaveToFile(nomefile, .....);

dove "nomefile" è il nome ritornato dalla TSaveDialog.

Ciao
Titolo: Re:Come aprire e leggere un banale file di testo? [RISOLTO]
Inserito da: AlexLazarus - Ottobre 24, 2022, 11:17:54 am
FUNGE TUTTO: GRAZIE DI NUOVO!  :)
Titolo: Re:Come aprire e leggere un banale file di testo? [RISOLTO]
Inserito da: DragoRosso - Ottobre 24, 2022, 11:39:09 am
Una sola attenzione: occhio alla codifica del file di testo (sia in lettura che in scrittura). Questo in particolare se i file vengono creati e letti da sistemi diversi (es: PC Francese e PC Inglese, peggio ancora se Cinese / Italiano ;D ).

Lazarus dovrebbe essere in grado di usare la corretta codifica, ma questo avviene se il file di testo è stato creato secondo alcune regole.

Per codifiche si intendono: "Ansi", "UTF8", "UTF16LE", "UTE16BE", "UTF ", etc ...

In alternativa se il file non venisse correttamente letto, si può forzare la codifica definendo il parametro "AEncoding" dei metodi "LoadFromFile" e SaveToFile".

Ciao
Titolo: Re:Come aprire e leggere un banale file di testo? [RISOLTO]
Inserito da: giacomarko - Ottobre 24, 2022, 12:16:48 pm
Due considerazioni:
a. A meno di un errore di copia ed incolla, così come è scritto il codice, mi sembra che le istruzioni di accesso al file, vengano eseguite indipendentemente dal fatto che il file esista o meno, in pratica il blocco di verifica dell'esistenza del file di testo, non inibisce l'accesso nel caso in cui non esista, no?

b. L'uso di una variabile locale di tipo boolean, ti eviterebbe di chiamare due volte la funzione FileExists(NomeFile)

codice originale:
procedure TForm1.Button1Click(Sender: TObject);
Var NomeFile, Elemento: string;
Var F: system.Text;

begin
  NomeFile:= 'D:\IlMioFile.txt' ;

  if FileExists(NomeFile) then
      Begin
        ShowMessage('Il file: ' + NomeFile + ' esiste');
      end
        else if  FileExists(NomeFile) =False Then
        ShowMessage('Il file: ' + NomeFile + ' NON esiste');
// ---- il blocco da qui in avanti non è subordinato al fatto che il test sia solo positivo
AssignFile(F,'D:\IlMioFile.txt');
reset (F);
FileOpen('D:\IlMioFile.txt',1);
While Not EOF(F) Do ReadLn(F, Elemento);
writeln(1,Elemento);
end;


suggerimento di codice rivisto:
procedure TForm1.Button1Click(Sender: TObject);
Var
  NomeFile, Elemento: string;
  F: system.Text;
ok: boolean;
begin
  NomeFile:= 'D:\IlMioFile.txt' ;
  ok := FileExists(NomeFile);
  if ok then
  Begin
    ShowMessage('Il file: ' + NomeFile + ' esiste');
    AssignFile(F,'D:\IlMioFile.txt');
    reset (F);
    FileOpen('D:\IlMioFile.txt',1);
    While Not EOF(F) Do ReadLn(F, Elemento);
    writeln(1,Elemento);
  end
  else  ShowMessage('Il file: ' + NomeFile + ' NON esiste');
end;

Oltre al suggerimento sull'uso di TStringList o TListBox, potrei suggerire direttamente un TMeno, questo permette di scorrere in su e giù il file come un normale editor, e con SaveToFile, anche salvare su disco le modifiche... ma questo dipende dall'utilizzo che devi farne e sopratutto se il contenuto deve essere visibile a video o meno.
Titolo: Re:Come aprire e leggere un banale file di testo? [RISOLTO]
Inserito da: DragoRosso - Ottobre 24, 2022, 02:42:11 pm
Ho tralasciato di commentare il codice fornito all'inizio del topic in quanto davo per scontato che la strada fosse l'uso del componente TListBox come indicato, ma visto che viene riproposto devo segnalarvi che l'uso di AssignFile e FileOpen contemporaneamente sullo stesso file non và assolutamente eseguito !!!

    AssignFile(F,'D:\IlMioFile.txt');  <--------------
    reset (F);
    FileOpen('D:\IlMioFile.txt',1);   <--------------

In questo caso è particolarmente "pericoloso" in quanto con "AssignFile" e la successiva operazione di "Reset" il file stesso viene aperto in "SOLA LETTURA", mentre con l'operazione FileOpen(..., 1) viene aperto in "SOLA SCRITTURA" (1 = fmopenwrite).

La funzione FileOpen comunque fallisce (almeno dovrebbe  :o ) in quanto il file è già "bloccato" in sola lettura e nessuno può aprirlo in scrittura, quindi non ci sono danni particolari (tanto più che l'handle ritornato dal FileOpen non viene neppure usato ... e questo non DEVE MAI ACCADERE !!!), ma una successione di simili operazioni potrebbe provocare qualche problemino ... e neanche tanto "ino" in occasioni diverse.

Ciao
Titolo: Re:Come aprire e leggere un banale file di testo? [RISOLTO]
Inserito da: giacomarko - Ottobre 24, 2022, 03:57:03 pm
Vero !!

mi sono soffermato solo sul flusso logico, e non sulle singole istruzioni

grazie
Titolo: Re:Come aprire e leggere un banale file di testo? [RISOLTO]
Inserito da: AlexLazarus - Ottobre 24, 2022, 06:25:39 pm
Due considerazioni:  .... eccetera.... ]

Ti ringrazio: in effetti ho apportato la razionale modifica suggerita (OK Boolean), però seguendo il percorso originario che avevo scelto (vedi screenshot)
Nasce comunque (e ti pareva...) qualche nuovo problema:

1) Come salvare un file (dopo aver scelto nome/percorso con il solito NomeFile:= OpenDialog1.FileName;) prelevando le varie righe (UNA SOLA ALLA VOLTA!) dal ListBox?
2) Come leggere un file NON tutto insieme (sl.LoadFromFile(NomeFile);) MA un rigo solo alla volta, in modo da esaminarlo ed - eventualmente - trattarlo singolarmente?

Grazie a tutti davvero, siete tutti molto disponibili.
Titolo: Re:Come aprire e leggere un banale file di testo? [RISOLTO]
Inserito da: DragoRosso - Ottobre 24, 2022, 07:44:37 pm
Intanto, @AlexLazarus e @giacomarko, cercate di usare il "code" (il diesis o cancelletto) per identificare il codice.

....

Esattamente come avevi fatto all'inizio .... aprendo il file e leggendolo con readln:

Codice: [Seleziona]
procedure TForm1.Button1Click(Sender: TObject);
Var
  NomeFile, Elemento: string;
  F: system.Text;
begin
ListBox1.Clear;
if OpenDialog1.Execute then
  begin
     NomeFile := OpenDialog1.FIleName;
     if FileExists(NomeFile) then
       begin
          AssignFile(F, NomeFile);
          reset (F);
          while Not EOF(F) Do
             begin
                ReadLn(F, Elemento);
                //Qui testi la riga letta, la modifichi, etc .... poi la puoi inserire nella ListBox
                ListBox1.Items.Add(Elemento);
             end;
          CloseFile(F);
       end;
  end
else
  begin
    //Qui esegui qualcosa se l'utente ha premuto il tasto "annulla"
  end;
end;

Ora per la scrittura dovresti, sulla base di quanto sopra e quanto detto nei post, riuscire a cavartela ... un pò di esercizio e di spremitura di meningi fà bene .....

Comunque se hai problemi siamo qua.

Ciao
Titolo: Re:Come aprire e leggere un banale file di testo? [RISOLTO]
Inserito da: DragoRosso - Ottobre 24, 2022, 09:14:17 pm
Questo per scrivere, caso mai avessi trovato problemi ...  ;)

Codice: [Seleziona]
procedure TForm1.Button1Click(Sender: TObject);
Var
  i: integer;
  NomeFile, Elemento: string;
  F: system.Text;
begin
ListBox1.Clear;
if SaveDialog1.Execute then
  begin
     NomeFile := SaveDialog1.FIleName;
     try
       AssignFile(F, NomeFile);
       ReWrite(F);
       for i := 0 to ListBox1.Items.Count -1 do
         begin
           Elemento := ListBox1.Items[i];
           //Qui testi la riga letta, la modifichi, etc .... poi la puoi scrivere nel file
           WriteLn(F, Elemento);
         end;
     except on e: exception do
       ShowMessage(e.Message);
     end;
     CloseFile(F);
  end
else
  begin
    //Qui esegui qualcosa se l'utente ha premuto il tasto "annulla"
  end;
end;

Ciao
Titolo: Re:Come aprire e leggere un banale file di testo? [RISOLTO]
Inserito da: AlexLazarus - Ottobre 25, 2022, 07:06:36 am
Questo per scrivere, caso mai avessi trovato problemi ...  ;)
Perfetto, sembra proprio ciò che mi serviva e che non ero riuscito a trovare, nonostante la spremitura - credimi - di tutte le meningi e dei neuroni di cui dispongo! ;)
Più tardi mi metto all'opera...