Visualizzazione dei risultati da 1 a 10 su 10

Discussione: Prolema lettura file

  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    21

    Prolema lettura file

    Salve a tutti,
    Ho dei problemi a gestire la lettura di un file, la questione è la seguente...
    Io dovrei leggere un file di testo composto da lettere che sono delimitate da un codice che è sempre lo stesso, del tipo
    <Codice sempre uguale>
    riga1
    riga2
    ...
    rigaN
    <Codice sempre uguale>
    riga1
    riga2
    ...
    rigaN
    <Codice sempre uguale>

    e cosi' via, il problema è che questo file di testo è enorme quindi non posso fare la lettura dell'intero file e metterlo in un arraylist, quindi vorrei eseguire la lettura lettera per lettera.
    Il codice che ho provato ad usare è

    codice:
    protected static ArrayList<String> ottieniSingolaLettera(BufferedReader reader)
    	{
    		ArrayList<String> lettera = null;		
    		try
    		{			
    			String letto = reader.readLine();
    			while(letto!=null)
    			{
    				if(letto.length()>2)
    				{
    					if(letto.substring(0,3).matches("3LettereCodice"))
    					{	
    						lettera= new ArrayList<String>();
    						lettera.add(letto);					
    						letto=reader.readLine();					
    						while(!letto.substring(0,3).matches("3LettereCodice"))
    						{
    							lettera.add(letto);					
    							letto=reader.readLine();
    						}
    						break;
    
    					}
    					else
    						letto=reader.readLine();
    				}
    			}
    		}
    		catch(Exception e)
    		{
    			System.out.println(e.getMessage());
    		}
    		return lettera;
    	}
    Pensavo di aprire nel main un buffered reader e usare sempre quello in un ciclo per gestire una per una le lettere.

    Il problema cosi' è che praticamente mi legge una lettera si e una no perchè l'ultimo readline contiene il codice che fa da interruzione e quindi quando rientra nel metodo rifà il readline e salta alla lettera successiva...

    Qaulcuno sa come potrei uscirne vivo?
    Grazie in anticipo per le risposte

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Prolema lettura file

    Originariamente inviato da Wahnsinn
    Qaulcuno sa come potrei uscirne vivo?
    Spiegando innanzitutto "a parole" cosa dovrebbe restituire concettualmente quel metodo.

    Perché il codice è confuso, poco pulito: fai più volte la readLine (discutibile), nel ciclo di lettura quando trovi quella parola fissa istanzi un nuovo ArrayList e lo riassegni a 'lettera', buttando via l'ArrayList che prima era referenziato (discutibile ... non so che ti serve tale logica).

    Quindi spiega a parola cosa volevi fare.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    21
    Si effettivamente rileggendo il post è poco chiaro , chiedo scusa ho postato di fretta...
    Allora...
    la situazione è questa io devo leggere un file che contiene n lettere, leggerle una per una, controllare se sono valide e se lo sono aggiungerle a un arraylist risultato.

    praticamente io vorrei che la funzione mi tirasse fuori una sola lettera ,ovvero tutte le stringhe che vanno dal codice che fa da interruzione, e la riga prima del prossimo codice di interruzione e si "ricordi" a che punto stava.
    Vorrei tirar fuori un arraylist di stringhe (che rappresenta la lettera) di questo tipo
    <Codice>
    riga1
    ...
    rigaN

    usare dei metodi su quest'arraylist(nello specifico delle funzioni che controllano se la lettera è valida o no) e poi leggere la lettera successiva.

    Finora semplicemente mettevo il contenuto di tutto il file di input in un arraylist e poi mi tiravo fuori le singole lettere dall'arraylist, ma usando in input un file da 50 MB il programma da un eccezione di heap memory.

    Quindi quello che vorrei fare ora è leggere di volta in volta solo una lettera, controllare se è valida, e passare a quella successiva in modo da dover leggere una piccola porzione del file ogni volta.
    Quello che volevo capire è come fare in modo che il reader capisca da che punto deve partire ogni volta.

    quello che pensavo io era una cosa del genere(che può essere tranquillamente errata non essendo io un mago della programmazione come avrete notato :P)
    codice:
    BufferedReader reader = funzioneCheRecuperaBufferedReader();
    ArrayList<String> lettera = new ArrayList<String>();
    while(lettera!= null)
        {
               lettera=ottieniSingolaLettera(reader);
               //funzioni che controllano se la lettera è valida
         }

    il codice del post precedente in ogni caso sostanzialmente fa...
    -dichiara un arraylist che rimarrà null se non incontra neanche una volta il codice di interruzione lettera

    -legge la prima riga

    -inizia un ciclo che finisce quando finisce il file

    -controlla se la riga letta è maggiore di 2 caratteri, se lo è legge i primi 3 caratteri della riga per controllare se è il codice di interruzione

    -Se la riga corrisponde al codice di interruzione lo aggiunge all'arraylist lettera e fa un ciclo per infilarci tutte le righe che incontra finchè non trova il prossimo codice di interruzione, quando lo trova esce dal ciclo e ritorna la lettera

    Il problema per com'è ora il codice è che con l'ultima readline legge il codice di interruzione, quindi quando richiamo il metodo una seconda volta come prima cosa mi fa un'altra readline quindi "salta" quella riga(e quindi mi salta tutta la seconda lettera) e mi va a trovare direttamente la lettera successiva(la terza)

    Mi scuso ancora per essere stato poco chiaro, spero di aver fatto un po' più di chiarezza. Ad ogni modo è ben accetto qualsiasi tipo di consiglio essendo un programmatore alle prime armi...

    Grazie della disponibilità,Ciao

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Wahnsinn
    devo leggere un file che contiene n lettere, leggerle una per una, controllare se sono valide e se lo sono aggiungerle a un arraylist risultato.
    Io dalla struttura generica che hai indicato, vedo solo che ci sono N righe separate ogni tanto da un "codice" fisso.
    Quindi le tue lettere come sono? Una sola lettera per riga?
    Ma fare un esempio pratico?? No?

    Tipo:

    codice:
    UNCODICE
    a
    b
    c
    UNCODICE
    d
    e
    f
    UNCODICE
    Tu vuoi che una prima invocazione di questo "tuo" metodo ti fornisca un ArrayList con "a","b","c" e una seconda successiva invocazione ti fornisca un altro ArrayList con le lettere nel blocco successivo cioè "d","e","f" e così via ...???

    Originariamente inviato da Wahnsinn
    codice:
    BufferedReader reader = funzioneCheRecuperaBufferedReader();
    ArrayList<String> lettera = new ArrayList<String>();
    while(lettera!= null)
        {
               lettera=ottieniSingolaLettera(reader);
               //funzioni che controllano se la lettera è valida
         }
    No, se è come ho ipotizzato io sopra, non va bene dal punto di vista del "design".
    Dovresti definire una "tua" classe, che ha internamente il BufferedReader (che resta "vivo" tra una invocazione e l'altra di quel metodo e quindi mantenere internamente uno "stato" in modo che possa progredire in momenti successivi nella lettura di questo file.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    21
    Originariamente inviato da andbin
    Io dalla struttura generica che hai indicato, vedo solo che ci sono N righe separate ogni tanto da un "codice" fisso.
    Quindi le tue lettere come sono? Una sola lettera per riga?
    Ma fare un esempio pratico?? No?
    Allora il file di input è una cosa simile a questa
    ABCDE1234(codice interruzione)
    Pippo
    Roma
    21
    Via Roma 1
    ABCDE1234
    Pluto
    Bergamo
    35
    Via Lazio 19
    ABCDE1234
    Paperino
    Ascoli
    19
    Via Perugia 12

    Le righe tra un ABCDE1234 e l'altro sono variabli, solitamente sono uguali ma alcune lettere potrebbero avere qualche riga in più
    Ad esempio...

    ABCDE1234
    Minni
    Verona
    32
    Via Topolinia 120
    Morta

    io vorrei prendere in considerazione la prima lettera
    ABCDE1234
    Pippo
    Roma
    21
    Via Roma 1

    lavorarci sopra, invocare nuovamente la funzione e passare alla successiva
    ABCDE1234
    Pluto
    Bergamo
    35
    Via Lazio 19

    e cosi' via...

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Wahnsinn
    io vorrei prendere in considerazione la prima lettera
    ABCDE1234
    Pippo
    Roma
    21
    Via Roma 1
    Ma LOL. Io intendevo "lettera" = "carattere" (a b c ....)
    Tu intendevi "lettera" in senso di "insieme di dati per la spedizione postale".

    Questo è quello che succede quando non precisi fin dall'inizio di cosa parli e dici solo "dovrei leggere un file di testo composto da lettere" e poi fai l'esempio mettendo riga1, riga2 ecc... e NON si capisce una mazza lettere di che cosa .......

    Originariamente inviato da Wahnsinn
    lavorarci sopra, invocare nuovamente la funzione e passare alla successiva
    Bene, e lo ripeto: fai una tua classe che ha il BufferedReader e che legge ma si ferma quando trova la riga di deliminazione.
    Con una piccola accortezza. Quel codice fa da separatore, quindi una riga di quel codice indica la terminazione di un blocco ma anche l'inizio del successivo.
    Per il primissimo blocco, il codice indica solo l'inizio quindi dovresti semplicemente "saltarlo". Quindi leggi finché non prendi il successivo codice.
    Per il blocco successivo, hai già letto prima il codice, quindi semplicemente vai avanti a leggere cercando il successivo codice.
    Il succo è semplice: solo il primo codice è "particolare" e quindi dovresti tenerti un "flag" che dice se è il primo blocco oppure no.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    21
    Originariamente inviato da andbin


    Questo è quello che succede quando non precisi fin dall'inizio di cosa parli e dici solo "dovrei leggere un file di testo composto da lettere" e poi fai l'esempio mettendo riga1, riga2 ecc... e NON si capisce una mazza lettere di che cosa .......
    Ops chiedo venia... comunque ora provo a lavorarci su e vedo se riesco che riesco a combinare...grazie delle dritte!

  8. #8
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    21
    Dunque, ho provato a risolvere con il seguente codice...(dove P01 è il famoso codice di interruzione)

    codice:
    public class LetturaFile 
    {
    	private BufferedReader reader;
    	private String riga;
    	private String percorsoFile;
    	private ArrayList<String> lettera;
    	private boolean primaLettera =true;	
    	
    	
    	public LetturaFile(String percorsoFile)
    	{
    		this.percorsoFile=percorsoFile;
    		this.reader = RecuperoValori.ottieniBufferedReader(percorsoFile);
    	}
    	public  String leggi()
    	{		
    		try
    		{
    			riga= reader.readLine();
    		}
    		catch(IOException e)
    		{
    			System.out.println(e.getMessage());
    		}
    		return riga;
    	}
    	
    	ArrayList<String> ottieniLettera()
    	{
    		if(primaLettera)
    		{
    		        riga =leggi();
    		}		
    		while(riga!=null)
    		{
    			if(IsCodiceInterruzione())
    			{				
    				lettera= new ArrayList<String>();
    				lettera.add(riga);
    				try {
    					riga=reader.readLine();
    				} catch (IOException e) {
    					System.out.println(e.getMessage());
    				}
    				aggiungiRighe();				
    				return lettera;
    			}
    			else
    				riga=leggi();
    		}
    		return null;
    	}
    	
    	ArrayList<String> aggiungiRighe()
    	{
    		
    		while(!riga.substring(0,3).matches("P01"))
    		try 
    		{
    			lettera.add(riga);
    			riga= reader.readLine();
    			if(riga==null)
    			{
    				break;
    			}
    		} 
    		catch (IOException e) 
    		{
    			System.out.println(e.getMessage());
    			e.printStackTrace();
    		}
    		primaLettera=false;
    		
    		return lettera;
    		
    	}
    	
    	boolean IsCodiceInterruzione()
    	{
    		if(riga.length()>2 && riga.substring(0,3).matches("P01"))
    			return true;
    		else return false;
    	}
    }


    che mi da il seguente errore:

    Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOfRange(Arrays.java:3209)
    at java.lang.String.<init>(String.java:215)
    at java.io.BufferedReader.readLine(BufferedReader.jav a:331)
    at java.io.BufferedReader.readLine(BufferedReader.jav a:362)
    at oggetti.LetturaFile.aggiungiRighe(LetturaFile.java :80)
    at oggetti.LetturaFile.ottieniLettera(LetturaFile.jav a:64)
    at oggetti.LetturaFile.ottieniRisultatoFiltrato(Lettu raFile.java:114)

    (non ho postato il codice di ottieniRisultatoFiltrato perchè sarebbe poco comprensibile...)

    La cosa che non riesco a capire è perchè se lo faccio partire senza interfaccia grafica funziona tranquillamente mentre se "monto" la funzione su interfaccia grafica va spedito fino alla lettera numero 6700~ dopodichè inizia a rallentare e dopo un altro centinaio di lettere va in eccezione...
    (PS qualsiasi suggerimento per migliorare il codice è sempre ben gradito ...)

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Wahnsinn
    ho provato a risolvere con il seguente codice...
    No, mi spiace. È solo lungo, fumoso e oltretutto la gestione delle eccezioni non è nemmeno "appropriata".

    È molto molto più semplice e logico, se vuoi posso postare una traccia/pseudo codice. Ma non di più ....
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  10. #10
    Utente di HTML.it
    Registrato dal
    Nov 2009
    Messaggi
    21
    Eh, magari...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.