Lettura ciclica da file

di il
3 risposte

Lettura ciclica da file

Salve,

dovrei realizzare un programma in Java che legge da file, estrapolare le informazioni e inviarle al Database. Infine cancellare il file.

Nuovamente mi verrà inviato un nuovo file (stesso nome del precedente) e ripetere le operazioni su citate.

Non capisco come fare un programma che è sempre in attesa di un file. Questo programma dovrebbe lavorare 24h su 24.

Qualcuno può aiutarmi a capire?

Grazie

3 Risposte

  • Re: Lettura ciclica da file

    RoboTony ha scritto:


    Non capisco come fare un programma che è sempre in attesa di un file. Questo programma dovrebbe lavorare 24h su 24.

    Qualcuno può aiutarmi a capire?
    Se ti basta un approccio in "polling" allora ti basta testare la presenza del file ogni tot di tempo. A livello basilare un ciclo continuo in cui usi isFile() di java.io.File per verificare se esiste o no. Se esiste lo elabori. Alla fine attendi comunque un tot di tempo. A livello un po' più avanzato, con un "timer" (java.util.Timer) per schedulare del codice ogni tot di tempo.

    Se non è quello che vuoi, chiarisci.
  • Re: Lettura ciclica da file

    Ho il seguente codice:

    package leggifile;

    import java.io.*;
    import java.nio.file.Files;

    public class LeggiFile {

    public static void main(String[] args) throws Exception {

    File dir;
    FileReader dirFile;
    String s;
    BufferedReader b;

    dir = new File("C:\\Users\\Utente\\Desktop\\Test\\prova.txt");
    dirFile = new FileReader(dir);
    b = new BufferedReader(dirFile);

    while(true) {

    //Se è presente un file
    if(dir.isFile()) {

    dirFile.ready();
    while(true) {

    s = b.readLine();

    //Quando arriva a fine stringa esce dal ciclo
    if(s==null) {

    break;

    }
    System.out.println(s);
    }
    dirFile.close(); //La risorsa viene rilasciata
    Files.deleteIfExists(dir.toPath()); //Infine può cancellare il file
    }
    }
    }
    }



    Quando all'istante iniziale il file non è presente va in errore perché il path "C:\\Users\\Utente\\Desktop\\Test\\prova.txt" non esiste

    Inoltre se il file è presente leggo, cancello il file, inserisco nella cartella nuovamente un file ma ho questo errore:

    Exception in thread "main" java.io.IOException: Stream closed
    at sun.nio.cs.StreamDecoder.ensureOpen(StreamDecoder.java:46)
    at sun.nio.cs.StreamDecoder.ready(StreamDecoder.java:184)
    at java.io.InputStreamReader.ready(InputStreamReader.java:195)
    at leggifile.LeggiFile.main(LeggiFile.java:24)
    C:\Users\Utente\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
    BUILD FAILED (total time: 3 minutes 42 seconds)
  • Re: Lettura ciclica da file

    Ciao!
    Inoltre se il file è presente leggo, cancello il file, inserisco nella cartella nuovamente un file ma ho questo errore:

    Exception in thread "main" java.io.IOException: Stream closed
    at sun.nio.cs.StreamDecoder.ensureOpen(StreamDecoder.java:46)
    at sun.nio.cs.StreamDecoder.ready(StreamDecoder.java:184)
    at java.io.InputStreamReader.ready(InputStreamReader.java:195)
    at leggifile.LeggiFile.main(LeggiFile.java:24)
    C:\Users\Utente\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
    BUILD FAILED (total time: 3 minutes 42 seconds)
    il problema è che il BufferedReader viene istanziato una sola volta (al di fuori del ciclo) e poi chiuso, quindi l'errore che ti si presenta al giro successivo è normale.

    Oltre a questo un while(true) senza temporizzazione per verificare la presenza del file o meno, la trovo poco performante e molto esosa in termini di risorse e potrebbe degradare di parecchio le prestazioni della macchina che sta facendo girare l'applicazione.
    Ti consiglierei l'uso delle classi Timer e TimerTask per schedulare il lavoro ogni tot di tempo (in modo tale da pianificare un controllo ad una certa ora o dopo che è passato un tot di tempo dall'esecuzione precedente).

    All'interno del TimerTask fare uno sviluppo di questo tipo:
    
    class CopyFile extends TimerTask {
    	@Override
    	run(){
    		Path path = Paths.get("C:\\Users\\Utente\\Desktop\\Test\\prova.txt");
    
    		// Verifico se esiste ed è un file, altrimenti termino l'esecuzione
    		if (!Files.exists(path) || !Files.isRegularFile(path)) {
    			return;
    		}
    	
    		BufferedReader b = Files.newBufferedReader(path, StandardCharsets.UTF_8); //se il file contiene un Charsets diverso, cambia il secondo parametro
    
    		while(true) {
    			....
    		}	
    	}
    }
    
    Buttata li eh.. Il codice l'ho scritto direttamente qui..
    Le classi Path e Files sono di Java 1.7, se devi usare una versione più vecchia, puoi mantenere la gestione della classe File come avevi fatto tu, ma sempre all'interno di un TimerTask.
    Eventualmente, valuta di rinominare il file prima di cominciare a leggere per non incorrere in problemi di concorrenza di accesso con l'applicazione che ti scrive il file.. Puoi utilizzare il metodo statico Files.move(...) che ti ritorna l'istanza di una nuova Path (e da li far partire il codice scritto sopra)
Devi accedere o registrarti per scrivere nel forum
3 risposte