2015-06-23 14 views
5

Mam klasę PDF, która implementuje interfejs fileReader.Problemy z zakresem zmiennych podczas korzystania z try-catch w Javie

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); 
} 

Zauważyłem, że istnieją problemy zakres zmiennych fin.

Kolejna realizacja zrobiłem było:

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; 
    } 

Ale teraz nie może uzyskać dostępu fileContent.

Jak mogę połączyć try-catches, aby nie mieć problemów z zasięgiem? Czy istnieje lepsze podejście do projektowania tego problemu? Muszę tworzyć funkcje do czytania trzech różnych typów plików.

+2

Jakie są dokładnie problemy z zasięgiem? –

Odpowiedz

5

Ponieważ Java 7 można połączyć try-catch następująco:

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(); 
    } 

które moim zdaniem sprawia, że ​​odkurzacz kod i zmienne zakresy bardziej oczywiste.

+1

O tak, lubię to o wiele lepiej niż sugerowałem. Nie wiedziałem, że to możliwe. Nauka czegoś nowego :) – DrZoo

+1

@DrZoo: To jest piękno Java, utrzymuje cię na palcach;) – StuPointerException

+0

Próbowałem tego, ale otrzymuję 'Alternatywy w oświadczeniu wielogłosowym nie mogą być powiązane przez podklasę Alternatywne java.io.FileNotFoundException jest podklasą alternatywnego java.io.IOException ". Używam Java7 na Intellij –

3

Można zagnieżdżać Try oświadczenia haczyk:

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; 

pamiętać, że dodałem Close() w klauzuli finally oczyścić. Również zwracanie wartości null prawdopodobnie nie jest tym, czego potrzebujesz w przypadku błędu, ale to jest specyficzne dla aplikacji.

+0

Rozumiem. Próbowałem tego, ale w niewłaściwy sposób. Dzięki –

2

Możesz mieć jeden try z wieloma blokami catch.

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

Można zmodyfikować tę część:

 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(); 
     } 

Przez

{ 
...... 
     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

To zależy od wersji Java, jeśli pracujesz z Javy 7 lub nowszym możesz użyć tylko jednego bloku catch, takiego jak ten catch (IOException | FileNotFoundException e) –

1

chciałbym napisać tak:

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

Ponieważ Java 7, jest tam ładne metody narzędziowe do odczytu całej zawartości pliku:

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

Ta metoda otworzy i zamknie obiekt FileInputStream, więc nie musisz tego robić samodzielnie. Zgłasza wyjątek IOException, jeśli coś pójdzie nie tak. Zazwyczaj, to najlepiej niech to wyjątek propagować do rozmówcy, ale jeśli naprawdę chcesz, aby powrócić zerowa w tym przypadku, można tego dokonać w następujący sposób:

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

ten posiada również piękny zaletę, że wartość zwracana w przypadek ten jest wyraźny - czy naprawdę chciałeś zwrócić tablicę wypełnioną wartościami 0, jeśli nie można już znaleźć pliku, tak jak to robi twój obecny kod?

Należy zauważyć, że ponieważ wyjątek NoSuchFileException jest podklasą wyjątku IOException, blok catch będzie obsługiwać oba.Jeśli chcesz się poradzić inaczej można napisać osobny blok catch dla 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; 
} 

Wreszcie należy wspomnieć, że prawdopodobnie kod odczyt pliku jest nieprawidłowa, jak InputStream.read() nie koniecznie przeczytać cały plik naraz. Dlatego zwraca liczbę odczytanych bajtów, aby można było wywołać ją ponownie dla reszty pliku. Ale jak już powiedziałem, od czasu Java 7 nie trzeba używać tak niskiego poziomu API (chyba że plik jest zbyt duży, aby zmieścił się w pamięci, oczywiście).

Powiązane problemy