Carregando arquivos com o ClassLoader

Este problema tem me incomodado por um tempo. Eu tenho que carregar alguns arquivos no meu aplicativo java, e a única maneira que eu comecei a trabalhar até agora parece com isso:

URL hsURL; if(System.getProperty("os.name").toLowerCase().contains("windows")) { hsURL = new URL("file:/" + System.getProperty("user.dir") + "/helpsets/helpset.hs"); } else { hsURL = new URL("file://" + System.getProperty("user.dir") + "/helpsets/helpset.hs"); } 

Mas isso é feio e terrível. Por um tempo eu pensei que tinha esse trabalho:

 hsURL = ClassLoader.getSystemResource("helpsets/helpset.hs"); 

Mas isso não funciona mais por algum motivo (eu devo ter mudado alguma coisa e não percebido. Ela retorna null.

Devo estar usando getResource () em vez de getSystemResource () (em caso afirmativo, por que é getSystemResource () estático, mas não getResource ())?

Eu estou usando o eclipse e tentei include a pasta no caminho de compilation (classpath) e não incluí-lo, não parece fazer a diferença.

getSystemResource é estático porque usará o classloader do sistema , que está disponível estaticamente. ( ClassLoader.getSystemClassLoader )

Se seu recurso estiver disponível no classpath, sugiro usar ClassLoader.getResource() ou Class.getResource de uma class apropriada, por exemplo

 Foo.class.getResource("/helpsets/helpset.hs"); 

( ClassLoader.getResource é “absolute”; Class.getResource é relativo ao pacote da class, a menos que você prefixe com um ‘/’.)

Se isso não funcionar, poste como seu aplicativo está configurado em termos de caminho de class e onde está o seu arquivo.

EDIT: Eu costumo encontrar o URL menos útil do que um InputStream , então eu uso getResourceAsStream vez de getResource . YMMV

Você mencionou várias coisas diferentes aqui, então vamos classificá-las.

1) Criando um “arquivo:” URL baseado em “user.dir”

A propriedade “user.dir” refere-se ao diretório de trabalho atual – onde quer que o usuário esteja quando iniciou o aplicativo. As chances são boas de que os arquivos gravados aqui desaparecerão entre duas execuções (porque o usuário pode ser executado em um diretório diferente).

A propriedade “user.home” refere-se ao diretório inicial do usuário – que deve permanecer o mesmo entre as execuções.

Em ambos os casos, use um object File para abrir arquivos, não crie uma URL “file:”. Você não tem nenhum benefício, e como você pode ver, você tem que escrever um código bagunçado para acessá-lo.

2) Recuperando um recurso através do classloader

Isso serve para recuperar arquivos que são empacotados com seu aplicativo – arquivos somente leitura. Como você viu, existem várias variantes. Eu prefiro usar o seguinte, porque eu suponho que uma class vai querer carregar um arquivo que é empacotado com ele.

 InputStream in = this.getClass().getClassLoader().getResourceAsStream(fileName);