Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 18

Discussione: Errore I/O

Hybrid View

  1. #1

    Errore I/O

    Salve
    Mi sto appena affacciando al mondo di java.
    In questo momento, sto creando un'applicazione a console, che cerca il file.zip passato come argomento, ne elenca i file e li estrae.
    Il codice è:
    codice:
    import java.util.*;
    import java.util.zip.*;
    import java.io.*;
    
    class extract {
        public static void main (String [] f) throws IOException {
            ZipFile Zf;
            try {Zf= new ZipFile (f[0]);}
            catch (ZipException e) {Zf=null;}
            catch (IOException e1) {Zf=null;};
            System.out.println("Decomprimo "+Zf.getName());
    
            Enumeration files = Zf.entries();
            while(files.hasMoreElements ()) {
                ZipEntry one = (ZipEntry) files.nextElement();
                System.out.println ("Estraggo "+one+" da "+Zf.getName());
                System.out.println("Dimensione compresso: "+one.getCompressedSize());
                System.out.println("Dimensione non compresso: "+one.getSize());
                System.out.println("CRC: "+one.getCrc());
                System.out.println("Modificato in data: "+one.getTime());
                
                InputStream in = Zf.getInputStream(one);
                FileOutputStream out= new FileOutputStream(one.getName());
    
                for (int ch=in.read();ch!=-1;ch=in.read()) {
                    out.write(ch);
                    out.close();
                    in.close();
                }
            }
        }
    }
    A parte il fatto che non riesco a capire le condizione dell'ultimo ciclo for (l'ho preso da una guida ), ho un errore di input/output su ogni zip che decido di estrarre. Tutto il resto dello script funziona (elenca i files, le dimensioni compresso e non, e il CRC), ma l'estrazione fallisce. Per completezza riporto l'output:
    Exception in thread "main" java.io.IOException: Stream closed
    at java.util.zip.InflaterInputStream.ensureOpen(Unkno wn Source)
    at java.util.zip.InflaterInputStream.read(Unknown Source)
    at extract.main(extract.java:25)
    Qualcuno sa spiegare cosa sto sbagliando?

  2. #2
    Utente di HTML.it L'avatar di minomic
    Registrato dal
    Nov 2010
    Messaggi
    635
    Ciao,
    "Stream closed" mi fa pensare che tu chiami il metodo close su qualche stream e poi tenti nuovamente di utilizzarlo. In particolare quel ciclo for mi sembra strano: fai un write e poi un close. All'iterazione successiva da per forza errore. Probabilmente il codice che hai visto era senza graffe e tu le hai aggiunte in maniera errata: le due close vanno fuori dal ciclo for.

  3. #3
    Quote Originariamente inviata da minomic Visualizza il messaggio
    Ciao,
    "Stream closed" mi fa pensare che tu chiami il metodo close su qualche stream e poi tenti nuovamente di utilizzarlo. In particolare quel ciclo for mi sembra strano: fai un write e poi un close. All'iterazione successiva da per forza errore. Probabilmente il codice che hai visto era senza graffe e tu le hai aggiunte in maniera errata: le due close vanno fuori dal ciclo for.
    Grazie, ho risolto, e grazie alle tue spiegazioni ho anche capito di più cosa stavo facendo.

  4. #4
    Utente di HTML.it L'avatar di Alex'87
    Registrato dal
    Aug 2001
    residenza
    Verona
    Messaggi
    5,802
    Che modo inefficiente di estrarre uno zip... non puoi leggere a buffer?
    SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
    Di questo libro e degli altri (blog personale di recensioni libri) | ​NO M.P. TECNICI

  5. #5
    Quote Originariamente inviata da Alex'87 Visualizza il messaggio
    Che modo inefficiente di estrarre uno zip... non puoi leggere a buffer?
    Come dicevo, sto giusto iniziando.
    Va beh, immagino di poter cominciare con:

    codice:
    BufferedReader br = new BufferedReader(new InputStreamReader(in));
    E poi, nel ciclo for avrò
    codice:
    ch=br.read()
    Sbaglio?

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Quote Originariamente inviata da Squaloattacca Visualizza il messaggio
    Sbaglio?
    La risposta alla domanda "Sbaglio?" è "sì"... BufferedReader è un aggeggo che serve a leggere stream di "caratteri". Quello che devi fare tu è leggere stream di byte (quindi, byte secchi, senza alcuna interpretazione di caratteri, che potrebbe falsare la lettura).

    Quello che intendeva dire Alex è che non ha molto senso leggere (e scrivere) un byte alla volta... conviene usare un array di byte (di una certa dimensione, generalmente multipli di 1024) in modo da "velocizzare" la lettura.


    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

  7. #7
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    La risposta alla domanda "Sbaglio?" è "sì"... BufferedReader è un aggeggo che serve a leggere stream di "caratteri". Quello che devi fare tu è leggere stream di byte (quindi, byte secchi, senza alcuna interpretazione di caratteri, che potrebbe falsare la lettura).

    Quello che intendeva dire Alex è che non ha molto senso leggere (e scrivere) un byte alla volta... conviene usare un array di byte (di una certa dimensione, generalmente multipli di 1024) in modo da "velocizzare" la lettura.


    Ciao.
    Ho notato: mi corrompe i file XD sto consultando la documentazione per trovare la soluzione. In base a cosa decido la dimensione del buffer?

    EDIT: per il momento sto adottando la seguente:
    codice:
    BufferedInputStream br = new BufferedInputStream(in);
    BufferedOutputStream bw = new BufferedOutputStream(out);
    dove in e out sono definiti nel codice originario. Non so che fare a quel ciclo for adesso
    Ultima modifica di Squaloattacca; 28-07-2014 a 14:01

  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Quote Originariamente inviata da Squaloattacca Visualizza il messaggio
    Ho notato: mi corrompe i file XD sto consultando la documentazione per trovare la soluzione. In base a cosa decido la dimensione del buffer?
    Generalmente "a tuo gusto". Diciamo che solitamente si vedono in giro valori che vanno dai 4 agli 8 KB (quindi 4 * 1024 o 8 * 1024), per tenersi "leggeri".


    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

  9. #9
    Utente di HTML.it L'avatar di Alex'87
    Registrato dal
    Aug 2001
    residenza
    Verona
    Messaggi
    5,802
    Non so cosa sia Zf e one.

    Io lo semplificherei un po' comunque, dando dei nomi decenti alle variabili


    codice:
    BufferedInputStream bis = new BufferedInputStream(Zf.getInputStream(one));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(one.getName()));
    
    byte[] buffer = new byte[4 * 1024];
    int bytesRead;
    
    while ((bytesRead = bis.read(buffer)) != -1) {
        bos.write(buffer, 0, bytesRead);
    }
    
    bos.close();
    bis.close();

    Controllare che la read restituisca qualcosa di strettamente maggiore di zero non è corretto: il valore restituito quando non c'è più nulla da leggere è -1.

    Manca inoltre la gestione delle eccezioni.
    Ultima modifica di Alex'87; 28-07-2014 a 14:47
    SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
    Di questo libro e degli altri (blog personale di recensioni libri) | ​NO M.P. TECNICI

  10. #10
    Quote Originariamente inviata da Alex'87 Visualizza il messaggio
    Non so cosa sia Zf e one.

    Io lo semplificherei un po' comunque, dando dei nomi decenti alle variabili


    codice:
    BufferedInputStream bis = new BufferedInputStream(Zf.getInputStream(one));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(one.getName()));
    
    byte[] buffer = new byte[4 * 1024];
    int bytesRead;
    
    while ((bytesRead = bis.read(buffer)) != -1) {
        bos.write(buffer, 0, bytesRead);
    }
    
    bos.close();
    bis.close();

    Controllare che la read restituisca qualcosa di strettamente maggiore di zero non è corretto: il valore restituito quando non c'è più nulla da leggere è -1.

    Manca inoltre la gestione delle eccezioni.
    Zf è di tipo ZipFile; nel codice per definirlo avevo fatto così:
    codice:
    ZipFile Zf;
            try {Zf = new ZipFile (file);}
            catch (ZipException e) {Zf=null;}
            catch (IOException e1) {Zf=null;};
            System.out.println("Decomprimo il file "+Zf.getName());
    Invece one è la ZipEntry corrispondente al file da estrarre:
    codice:
    ZipEntry one = (ZipEntry) list.nextElement ();
    che nel codice è in un while che la definisce file per file:
    codice:
    while (list.hasMoreElements()) {}
    e
    codice:
    Enumeration list = Zf.entries();
    Per semplificare il codice mi pare tu abbia direttamente eliminato le mie variabili di InputStream e FileOutputStream e le abbia messe direttamente nello scrittore e lettore con buffer...mi abituerò

    Per quanto riguarda le eccezioni:
    codice:
    try {
    BufferedInputStream bis = new BufferedInputStream(Zf.getInputStream(one));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(one.getName()));
    
    byte[] buffer = new byte[4 * 1024];
    int bytesRead;
    
    while ((bytesRead = bis.read(buffer)) != -1) {
        bos.write(buffer, 0, bytesRead);
    }
    
    bos.close();
    bis.close();
    }
    } catch (ZipException e) {System.out.println("Si è verificato un errore. Estrazione fallita");}
    catch (IOException e) {System.out.println("Errore di Input/Output. Estrazione fallita");};
    va bene così?

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.