Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    aprire file di testo molto pesanti

    mi ritrovo ad aprire file xml piuttosto pesanti
    attualmente sono sui 300kb (ma in futuro aumenteranno) e già così ci metto circa 30 secondi

    mi viene quindi il dubbio di usare codice poco efficiente:

    codice:
     try
            {
                FileInputStream fstream = new FileInputStream(percorso);
                DataInputStream in = new DataInputStream(fstream);
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
                String strLine;
                while ((strLine = br.readLine()) != null)
                   testo+=strLine+"\n";
                in.close();
               testo=testo.toString();
            }
            catch (IOException e)
            {
              System.out.println(e.getMessage());
            }
    è migliorabile oppure mi tocca aspettare quei tempi?

    grazie

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

    Re: aprire file di testo molto pesanti

    Originariamente inviato da ranza!!!123
    mi viene quindi il dubbio di usare codice poco efficiente
    E avresti indovinato, perché è proprio poco efficiente.

    Innanzitutto hai usato la "concatenazione" delle stringhe. Per ogni ciclo del while viene creato un nuovo StringBuffer (o StringBuilder da Java 5) in cui viene appeso testo, poi strLine e poi "\n" e quindi viene assegnato a testo il risultato del toString() del buffer. Per ogni riga!

    Inoltre leggi "a righe". A meno che tu "sappia" esattamente come è strutturato il documento, esso potrebbe avere 1 sola riga (tutti i tag uno dietro l'altro senza alcun newline) o un newline dopo ogni tag. Quindi leggere "a righe" è un po' una incognita in questo caso.

    Inoltre ancora il readLine() "butta" via la sequenza di newline letta e tu aggiungi fisso un "\n". Non è sbagliato di per sé (e dipende da cosa ci devi fare poi con il testo completo) ma non vedo perché si debbano alterare i newline (se non c'è un motivo preciso).


    No. La soluzione più efficiente è questa: istanzia un unico StringBuffer (o StringBuilder, Java5+), quindi leggi a "blocchi" di char (istanzia un array di "buffer" di es. 4096 char) e "butta" tutti i char letti nel buffer. E in tal caso servirebbe solo avere un InputStreamReader (non anche un BufferedReader perché saresti già tu a fare una sorta di "bufferizzazione" con il tuo array di char).


    P.S.1: Hai usato un DataInputStream in mezzo alla "catena" di stream che è assolutamente inutile in questo caso.
    P.S.2: La gestione delle eccezioni che hai fatto non è il massimo della accuratezza.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  3. #3
    ti ringrazio per la spiegazione

    lascio il codice ai posteri

    codice:
            StringBuffer sb = new StringBuffer ();
            InputStreamReader isr = null;        
            char[] buffer = new char[4096];
            int len;
            try
            {
                FileInputStream fis = new FileInputStream (percorso);
                isr = new InputStreamReader (fis);
                while ((len = isr.read (buffer)) > 0)
                    sb.append (buffer, 0, len);
                if (isr != null)
                    isr.close ();
                testo=sb.toString();
            }
            catch (IOException e)
                {
                  System.out.println(e.getMessage());
                }
    però non ho capito il discorso delle eccezioni..non basta la IO?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da ranza!!!123
    però non ho capito il discorso delle eccezioni..non basta la IO?
    La questione è che se la read() lancia una eccezione, il close() non lo fai (e vedo che sono pochi che colgono queste sottigliezze che però sono importanti per fare codice "solido"!).

    La cosa va fatta in modo più accurato e magari "incapsulando" la logica di lettura in un metodo, senza gestire lì dentro le eccezioni.

    codice:
    public static StringBuffer readTextFile(File f) throws IOException {
        FileInputStream fis = new FileInputStream(f);
        InputStreamReader isr = new InputStreamReader(fis);
    
        try {
            StringBuffer buf = new StringBuffer();
            char[] arrBuf = new char[4096];
            int len;
            
            while ((len = isr.read(arrBuf)) > 0) {
                buf.append(arrBuf, 0, len);
            }
            
            return buf;
        } finally {
            isr.close();
        }
    }
    E sarà il chiamante a dover prendere in considerazione la IOException. Perché nel metodo sopra la eccezione non è "gestita" (nel senso di catch-quindi-faccio-qualcosa) ma c'è solo il finally per garantire che la close venga sempre fatta.

    La vera gestione delle eccezioni andrà fatta quindi altrove.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,305
    Originariamente inviato da ranza!!!123
    però non ho capito il discorso delle eccezioni..non basta la IO?
    Aggiungo anche:

    Fai stampare lo stackTrace() così ottieni tutto il necessario per andare a correggere eventuali errori: ottieni il messaggio, il nome dell'eccezione, il nome della classe in cui si è verificato e la riga... più tutto il trace dei vari metodi richiamati per arrivare fin la.

    codice:
    } catch (IOException e) {
       e.printStackTrace();
    }

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

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 © 2024 vBulletin Solutions, Inc. All rights reserved.