2012-04-13 13 views
42

Mam wdrożoną moją aplikację do pliku JAR. Kiedy trzeba skopiować dane z jednego pliku zasobów do zewnętrznej pliku jar, mam ten kod:Plik JAR Java: użyj błędów zasobów: URI nie jest hierarchiczny

URL resourceUrl = getClass().getResource("/resource/data.sav"); 
File src = new File(resourceUrl.toURI()); //ERROR HERE 
File dst = new File(CurrentPath()+"data.sav"); //CurrentPath: path of jar file don't include jar file name 
FileInputStream in = new FileInputStream(src); 
FileOutputStream out = new FileOutputStream(dst); 
// some excute code here 

Błąd spotkałem jest: URI is not hierarchical. tego błędu nie spotykam po uruchomieniu w środowisku IDE.

Jeśli zmienić powyższy kod jako jakiejś pomocy na innym poście na StackOverflow:

InputStream in = Model.class.getClassLoader().getResourceAsStream("/resource/data.sav"); 
File dst = new File(CurrentPath() + "data.sav"); 
FileOutputStream out = new FileOutputStream(dst); 
//.... 
byte[] buf = new byte[1024]; 
int len; 
while ((len = in.read(buf)) > 0) { //NULL POINTER EXCEPTION 
    //.... 
} 

Odpowiedz

63

nie można zrobić tego

File src = new File(resourceUrl.toURI()); //ERROR HERE 

nie jest plik! Kiedy uciekniesz od ide, nie masz żadnego błędu, ponieważ nie uruchamiasz pliku JAR. W klasach IDE zasoby są wyodrębniane w systemie plików.

Ale można otworzyć InputStream w ten sposób:

InputStream in = Model.class.getClassLoader().getResourceAsStream("/data.sav"); 

Usuń "/resource". Zasadniczo IDE rozdziela się na klasach systemu plików i zasobach. Ale kiedy słoik jest tworzony, są one układane razem. Tak więc poziom folderu "/resource" jest używany tylko do oddzielania klas i zasobów.

Gdy otrzymasz zasób z programu ładującego klasy, musisz podać ścieżkę do zasobu, która jest prawdziwą hierarchią pakietów.

+0

Próbowałem ponownie na swój sposób (jest mój drugi kod powyżej), ale gdy jest to przejść: 'in.read (buf)' ---> Spełniam wyjątek punktowy null. :(@: resource jest folderem w moim projekcie, ma tę samą hierarchię z innym pakietem, więc muszę dodać 'resource' – hqt

+2

po hierarchii twojego projektu – dash1e

+5

Ale co, jeśli naprawdę POTRZEBUJĘ obiektu" File ". ..? – TekTimmy

0

Podczas gdy natknąłem się tym problemem sam chciałbym dodać inną opcję (w przeciwnym razie doskonałego wyjaśnienia od @ dash1e):

Eksportuj wtyczki jako katalogu (nie JAR), dodając:

Eclipse-BundleShape: dir 

na numer MANIFEST.MF.

Przynajmniej podczas eksportowania aplikacji RCP za pomocą kreatora eksportu (w oparciu o plik *.product) zostanie to uszanowane i zostanie utworzony folder.

7

Oto rozwiązanie dla Eclipse RCP/programistów wtyczki:

Bundle bundle = Platform.getBundle("resource_from_some_plugin"); 
URL fileURL = bundle.getEntry("files/test.txt"); 
File file = null; 
try { 
    URL resolvedFileURL = FileLocator.toFileURL(fileURL); 

    // We need to use the 3-arg constructor of URI in order to properly escape file system chars 
    URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null); 
    File file = new File(resolvedURI); 
} catch (URISyntaxException e1) { 
    e1.printStackTrace(); 
} catch (IOException e1) { 
    e1.printStackTrace(); 
} 

To bardzo ważne, aby użyć FileLocator.toFileURL(fileURL) zamiast resolve(fileURL) , Bo kiedy wtyczka jest zapakowany do słoika spowoduje Eclipse aby utworzyć rozpakowaniu wersja w tymczasowej lokalizacji, aby umożliwić dostęp do obiektu za pomocą pliku. Na przykład, myślę, że Lars Vogel ma błąd w swoim artykule - http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/

+0

Co to jest klasa platformy? Potrzebna jest biblioteka inna niż rt? – AndreyP

+1

@AndreyP to rozwiązanie jest przeznaczone dla programistów wtyczki eclipse rcp. Polecam wypróbować getResourceAsStream (...) podejście –

+0

W mojej stworzonej przez maven aplikacji RCP E4, pliki binarne dołączone do słoika muszą zostać rozpakowane i otwarte. Twoje rozwiązanie w końcu pozwoliło mi to zrobić i otworzyć 'file.getAbsolutePath()' w domyślnej przeglądarce systemu operacyjnego. –

6

Jeśli z jakiegoś powodu naprawdę trzeba utworzyć obiekt java.io.File do pkt do zasobu wewnątrz pliku JAR, odpowiedź jest tutaj: https://stackoverflow.com/a/27149287/155167

File f = new File(getClass().getResource("/MyResource").toExternalForm()); 
0

W uzupełnieniu do ogólnych odpowiedzi, można uzyskać „URI nie jest hierarchiczny” od Unitils biblioteki próbuje załadować zestawu danych off pliku .jar. Może się tak zdarzyć, gdy przechowujesz zbiory danych w jednym module częściowym, a rzeczywiste testy w innym module.

Istnieje nawet bug UNI-197 złożone.

Powiązane problemy