2012-12-30 14 views
32

Podążyłem za sposobem ładowania pliku zasobów przy użyciu getClass.getResource(path). Fragment kodu jest tutaj:Ładowanie pliku przez getClass(). GetResource()

String url = "Test.properties"; 

System.out.println("Before printing paths.."); 
System.out.println("Path2: "+ getClass().getResource(url).getPath()); 

FileInputStream inputStream = new FileInputStream(new File(getClass().getResource(url).toURI())); 
i_propConfig.load(inputStream); 
inputStream.close(); 

mam skonfigurowane w Eclipse z hierarchią (Under źródło znajduje się folder o nazwie SwingDemo W SwingDemo jest mój plik java jak również pliku zasobów.) ...

  1. src
    • SwingDemo
      1. CustomDialog.java
      2. Test.properties

Kiedy używam tego na zaćmienie wszystko działa prawidłowo. Ale jak tylko próbować uruchamiać aplikacje z cmd linii zerowej wyjątkiem wskaźnika jest występujących ..

Command Line hierarchia wdrażania jest następujący:

Folder: D:\Work\Java Progrms\SwingDemo

Hierarchia:

  1. SwingDemo
    • CustomDialog.java
    • Test.properties

Przede wszystkim skompilowany plik wewnątrz SwingDemo folderu z linii poleceń (javac CustomDialog.java). Potem przesunąć o jeden krok z powrotem do folderu Programy Java (jak wspomniałem pakiet wewnątrz .java klasie) i uruchamiać aplikacje za pomocą słynnego

java SwingDemo.CustomDialog 

użyłem do naśladowania podobnych kroków, gdy użyłem nowego FileInputStream ("ścieżkę ") poprzednio. Po wykonaniu tej czynności otrzymuję wyjątek wskaźnika pustego.

Myślę, że getClass().getResource(url) nie można załadować pliku z określonego katalogu. Właśnie dlatego umieściłem zasób w tym samym katalogu, co mój plik java. W Eclipse działało dobrze. Ale dlaczego powoduje to błąd podczas uruchamiania z wiersza poleceń.

Odpowiedz

61

getClass().getResource() używa programu ładującego klasy do załadowania zasobu. Oznacza to, że zasób musi znajdować się w ścieżce klasy, która ma zostać załadowana.

Kiedy robi to z Eclipse, wszystko można umieścić w folderze źródłowym jest „skompilowany” przez Eclipse:

  • pliki .java są kompilowane do.Pliki klasy, które wykraczają katalogu bin (domyślnie)
  • inne pliki zostaną skopiowane do katalogu bin (przestrzegającej pakietu/folderu hirearchy)

Podczas uruchamiania programu z Eclipse, katalog bin jest więc w Ścieżka klas, a ponieważ zawiera plik Test.properties, ten plik może zostać załadowany przez moduł ładujący klasy, używając getResource() lub getResourceAsStream().

Jeśli nie działa z wiersza poleceń, dzieje się tak dlatego, że plik nie znajduje się w ścieżce klas.

pamiętać, że nie powinien robić

FileInputStream inputStream = new FileInputStream(new File(getClass().getResource(url).toURI())); 

załadować zasobu. Ponieważ może to działać tylko wtedy, gdy plik jest ładowany z systemu plików. Jeśli zapiszesz aplikację w pliku jar lub załadujesz klasy przez sieć, nie zadziała. Aby uzyskać InputStream, wystarczy użyć

getClass().getResourceAsStream("Test.properties") 

i wreszcie, jako dokumentacja wskazuje

Foo.class.getResourceAsStream("Test.properties") 

załaduje plik Test.properties znajdujący się w tym samym pakiecie co klasa Foo.

Foo.class.getResourceAsStream("/com/foo/bar/Test.properties") 

załaduje plik Test.properties znajdujący się w opakowaniu com.foo.bar.

+2

To pomogło mi: „Jeśli pakiet twojej aplikacji do pliku JAR lub jeśli załadujesz klasy przez sieć, nie zadziała. " -> Zamiast tego musisz pobrać plik InputStream. –

6

Najlepszym sposobem uzyskania dostępu do plików z folderu zasobów wewnątrz słoika jest użycie InputStream poprzez getResourceAsStream. Jeśli nadal potrzebujesz zasobu jako przykład plik można skopiować zasobu w postaci strumienia do pliku tymczasowego (plik temp zostaną usunięte po wyjściu JVM):

public static File getResourceAsFile(String resourcePath) { 
    try { 
     InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath); 
     if (in == null) { 
      return null; 
     } 

     File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp"); 
     tempFile.deleteOnExit(); 

     try (FileOutputStream out = new FileOutputStream(tempFile)) { 
      //copy stream 
      byte[] buffer = new byte[1024]; 
      int bytesRead; 
      while ((bytesRead = in.read(buffer)) != -1) { 
       out.write(buffer, 0, bytesRead); 
      } 
     } 
     return tempFile; 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 
+0

Bardzo pomocna odpowiedź. Chciałbym móc głosować więcej razy: D. Myślę, że będzie mógł pracować również z tym wierszem kodu InputStream in = getClass(). GetResourceAsStream (resourcePath); – xXxpRoGrAmmErxXx

Powiązane problemy