2015-06-23 7 views
5

Ho una classe PDF che implementa un'interfaccia fileReader.Problemi nell'ambito delle variabili durante l'utilizzo di try-catch in Java

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 

public class PDF implements fileReader { 
    @Override 
    public byte[] readFile(File pdfDoc) { 
     if (!pdfDoc.exists()) { 
      System.out.println("Could not find" + pdfDoc.getName() + " on the specified path"); 
      return null; 
     } 
     FileInputStream fin = null; 
     try { 
      fin = new FileInputStream(pdfDoc); 
     } catch (FileNotFoundException e) { 
      System.out.println(""); 
      e.printStackTrace(); 
     } 
     byte fileContent[] = new byte[(int) pdfDoc.length()]; 
     try { 
      fin.read(fileContent); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return fileContent; 
    } 
} 

import java.io.File; 
public interface fileReader { 
    <T> T readFile(File fileObject); 
} 

Ho notato che ci sono problemi di ambito per le variabili fin.

Un'altra implementazione ho fatto è stato:

public byte[] readFile1(File pdfDoc) { 
     if (!pdfDoc.exists()) { 
      System.out.println("Could not find" + pdfDoc.getName() + " on the specified path"); 
      return null; 
     } 
     FileInputStream fin = null; 
     try { 
      fin = new FileInputStream(pdfDoc); 
      byte fileContent[] = new byte[(int) pdfDoc.length()]; 
      try { 
       fin.read(fileContent); 
      } catch (IOException e) { 
       System.out.println(""); 
       e.printStackTrace(); 
      } 
     } catch (FileNotFoundException e) { 
      System.out.println(""); 
      e.printStackTrace(); 
     } 
     return fileContent; 
    } 

Ma ora non ho potuto accedere fileContent.

Come è possibile combinare lo try-catches in modo da non avere problemi di ambito? Può esserci un approccio di progettazione migliore a questo problema? Devo fare funzioni per leggere tre diversi tipi di file.

+2

Quali sono esattamente i problemi del tuo ambito? –

risposta

5

Dal momento che Java 7 è possibile combinare la try-catch come segue:

FileInputStream fin = null; 
    try { 
     fin = new FileInputStream(pdfDoc); 
     byte fileContent[] = new byte[(int) pdfDoc.length()]; 
     fin.read(fileContent); 
    } catch (IOException | FileNotFoundException e) { 
     System.out.println(""); 
     e.printStackTrace(); 
    } 

che, a mio parere, rende il codice più pulito e di validità delle variabili più evidente.

+1

Oh bello, mi piace molto meglio di quello che ho suggerito. Non sapevo che fosse possibile. Imparare qualcosa di nuovo :) – DrZoo

+1

@DrZoo: Questa è la bellezza di Java, ti tiene in pugno;) – StuPointerException

+0

Ho provato questo, ma ottengo 'Le alternative in un'istruzione multi-catch non possono essere correlate tramite sottoclasse java.io.FileNotFoundException alternativo è una sottoclasse di java.io.IOException alternativa. Sto usando Java7 su Intellij –

3

È possibile nidificare i try dichiarazioni di cattura:

try { 
     FileInputStream fin = new FileInputStream(pdfDoc); 
     byte fileContent[] = new byte[(int) pdfDoc.length()]; 
     try { 
      fin.read(fileContent); 
      return fileContent; 
     } catch (IOException e) { 
     e.printStackTrace(); 
     } finally { 
     fin.close(); 
     } 

    } catch (FileNotFoundException e) { 
     System.out.println(""); 
     e.printStackTrace(); 
    } 
    return null; 

Nota che ho aggiunto un close() in una clausola finally per ripulire. E anche restituire null non è probabilmente quello che vuoi in caso di errore, ma è specifico dell'applicazione.

+0

Ho capito. L'avevo provato ma in modo sbagliato. Grazie –

2

È possibile avere uno try con più blocchi catch.

try { 
    //do stuff 
} 
catch (FileNotFoundException e) { 
     System.out.println(""); 
     e.printStackTrace(); 
} 
catch (IOException e) { 
     e.printStackTrace(); 
} 
2

è possibile modificare questa parte:

 FileInputStream fin = null; 
     try { 
      fin = new FileInputStream(pdfDoc); 
     } catch (FileNotFoundException e) { 
      System.out.println(""); 
      e.printStackTrace(); 
     } 
     byte fileContent[] = new byte[(int) pdfDoc.length()]; 
     try { 
      fin.read(fileContent); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

Con

{ 
...... 
     FileInputStream fin = null; 
     byte fileContent[]=null; 
     try { 
      fin = new FileInputStream(pdfDoc); 
      fileContent = new byte[(int) pdfDoc.length()]; 
      fin.read(fileContent); 
     } catch (FileNotFoundException e) { 
      System.out.println(""); 
      e.printStackTrace(); 
     }catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return fileContent 
    } 
+0

Dipende dalla versione di Java se stai lavorando con java 7 o più recente, puoi usare solo un blocco catch come questo catch (IOException | FileNotFoundException e) –

1

avrei scritto così:

public byte[] readFile(File pdfDoc) { 
    if (!pdfDoc.exists()) { 
     System.out.println("Could not find" + pdfDoc.getName() + " on the specified path"); 
     return null; 
    } 
    FileInputStream fin = null; 
    byte fileContent[] = new byte[(int) pdfDoc.length()]; 

    try { 
     fin = new FileInputStream(pdfDoc); 
     fin.read(fileContent); 
    } catch (FileNotFoundException e) { 
     System.out.println(""); 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     if (null != fin) { 
      fin.close(); 
     } 
    } 
    return fileContent; 
}
0

Dal Java 7, c'è una bella metodi di utilità per leggere l'intero contenuto di un file:

return Files.readAllBytes(pdfFile.toPath()); 

Questo metodo consente di aprire e chiudere FileInputStream per voi, quindi non è necessario farlo da soli. Genera una IOException se qualcosa va storto. Di solito, è meglio lasciare che questa eccezione si propagano al chiamante, ma se si vuole davvero restituire null in questo caso, è possibile ottenere questo risultato come segue:

try { 
    return Files.readAllBytes(pdfFile.toPath()); 
} catch (IOException e) { 
    e.printStackTrace(); 
    return null; 
} 

Questo ha anche il bel vantaggio che il valore restituito in quel caso è esplicito - o intendevi davvero restituire un array riempito con valori 0 se il file non può più essere trovato, come fa il tuo codice attuale?

Si noti che poiché NoSuchFileException è una sottoclasse di IOException, il blocco catch gestirà entrambi.Se si desidera gestire in modo diverso si può scrivere un blocco catch separato per il NoSuchFileException:

try { 
    return Files.readAllBytes(pdfFile.toPath()); 
} catch (NoSuchFileException e) { 
    System.err.println("Oh no, the file has disappeared."); 
    e.printStackTrace(); 
    return null; 
} catch (IOException e) { 
    System.err.println("The file exists, but could not be read."); 
    e.printStackTrace(); 
    return null; 
} 

Infine, forse dovrei dire che il codice di lettura del file non è corretto, come InputStream.read() non deve necessariamente leggere il intero file in una volta. Ecco perché restituisce il numero di byte letti in modo da poterlo richiamare per il resto del file. Ma come ho detto, dal momento che Java 7 non è necessario utilizzare API di basso livello (a meno che il file non sia troppo grande per adattarsi alla memoria, ovviamente).

Problemi correlati