Como obter o caminho absoluto para o arquivo na pasta / resources do seu projeto

90

Assuma a configuração padrão do maven.

Digamos que em sua pasta de recursos você tenha um arquivo abc.

Em Java, como posso obter o caminho absoluto para o arquivo, por favor?

James Raitsev
fonte
Você quer escrever um plugin Maven? Ou você deseja acessar o arquivo quando o programa for executado?
Gyro Gearless de
Existem três variantes de solução, dependendo da situação: stackoverflow.com/a/56327069/715269
Gangnus

Respostas:

69

Você pode usar o ClassLoader.getResourcemétodo para obter o recurso correto.

URL res = getClass().getClassLoader().getResource("abc.txt");
File file = Paths.get(res.toURI()).toFile();
String absolutePath = file.getAbsolutePath();

OU

Embora isso possa não funcionar o tempo todo, uma solução mais simples -

Você pode criar um Fileobjeto e usar o getAbsolutePathmétodo:

File file = new File("resources/abc.txt");
String absolutePath = file.getAbsolutePath();
Rahul Bobhate
fonte
8
Um conselho de uso limitado, já que depende do diretório de trabalho para ser a raiz do maven. E mesmo assim, você deve usar target/classes/abc.txtpara referenciar o arquivo, já que este é o lugar canônico onde o Maven coloca os arquivos de recursos após o processamento (por exemplo, o plugin maven-resources pode ter feito a substituição da propriedade em abc.txt). É muito melhor usar abc.txt via getResource () do classpath.
Gyro Gearless de
2
E se um usuário final estiver executando seu aplicativo como um JAR executável? Então não haverá um Arquivo físico. Este é outro motivo pelo qual você deve usar getResource () e, por exemplo, abrir o fluxo de entrada para ele, dependendo do que você deseja fazer com ele.
Matthew Wise
6
Isso pode ser removido como a resposta correta? @Karol S respondeu abaixo - essa deve ser a resposta correta (daí a discrepância de
voto positivo
3
Resposta errada. Consulte a resposta abaixo por @Karol
bhathiya-perera
165

A maneira correta que realmente funciona:

URL resource = YourClass.class.getResource("abc");
Paths.get(resource.toURI()).toFile();

Não importa agora onde o arquivo no caminho de classe está fisicamente, ele será encontrado contanto que o recurso seja realmente um arquivo e não uma entrada JAR.

(O aparentemente óbvio new File(resource.getPath())não funciona para todos os caminhos! O caminho ainda é codificado por URL!)

Karol S
fonte
5
Ou presumivelmente você poderia apenas fazer: new File(resource.toURI()).getAbsolutePath();(ou seja, não acho que você precisa do objeto Caminho?)
Dan King
1
Boa dica sobre o toURI (), isso evita que espaços em seu caminho saiam de% 20!
Matthew Wise
28
Obrigado! Isso quase funcionou para mim. Mas eu tive que fazer uma mudança: YourClass.class.getClassLoader (). GetResource ("abc");
yngwietiger
Você poderia alternativamente fazer new File(YourClass.class.getResource("abc").toURI().getPath())se quisesse.
Mike Rylander,
2
Não entendo como isso funcionou para tantas pessoas sem a barra inicial:.getResource("/abc")
cahen
27

Você precisa especificar o caminho iniciado a partir de /

URL resource = YourClass.class.getResource("/abc");
Paths.get(resource.toURI()).toFile();
Hett
fonte
12

Crie a instância classLoader da classe que você precisa, então você pode acessar os arquivos ou recursos facilmente. agora você acessa o caminho usando o getPath()método dessa classe.

 ClassLoader classLoader = getClass().getClassLoader();
 String path  = classLoader.getResource("chromedriver.exe").getPath();
 System.out.println(path);
Kirit Thakrar
fonte
1

Para retornar um arquivo ou caminho de arquivo

URL resource = YourClass.class.getResource("abc");
File file = Paths.get(resource.toURI()).toFile(); // return a file
String filepath = Paths.get(resource.toURI()).toFile().getAbsolutePath();  // return file path
Emmanuel Osimosu
fonte
0

Existem dois problemas em nosso caminho para o caminho absoluto:

  1. A colocação encontrada não será onde os arquivos de origem estão, mas onde a classe é salva. E a pasta de recursos quase com certeza estará em algum lugar da pasta de origem do projeto.
  2. As mesmas funções para recuperar o recurso funcionam de maneira diferente se a classe for executada em um plug-in ou em um pacote diretamente na área de trabalho.

O código a seguir nos dará todos os caminhos úteis:

    URL localPackage = this.getClass().getResource("");
    URL urlLoader = YourClassName.class.getProtectionDomain().getCodeSource().getLocation();
    String localDir = localPackage.getPath();
    String loaderDir = urlLoader.getPath();
    System.out.printf("loaderDir = %s\n localDir = %s\n", loaderDir, localDir);

Aqui, ambas as funções que podem ser usadas para localização da pasta de recursos são pesquisadas. Quanto a class, pode ser obtido de qualquer forma, estática ou dinamicamente.


Se o projeto não estiver no plug-in, o código, se executado em JUnit, imprimirá:

loaderDir = /C:.../ws/source.dir/target/test-classes/
 localDir = /C:.../ws/source.dir/target/test-classes/package/

Portanto, para chegar a src / rest / resources, devemos subir e descer na árvore de arquivos. Ambos os métodos podem ser usados. Observe, não podemos usar getResource(resourceFolderName), pois essa pasta não está na pasta de destino. Ninguém coloca recursos nas pastas criadas, espero.


Se a classe estiver no pacote que está no plug-in, a saída do mesmo teste será:

loaderDir = /C:.../ws/plugin/bin/
 localDir = /C:.../ws/plugin/bin/package/

Portanto, novamente devemos subir e descer na árvore de pastas.


O mais interessante é o caso quando o pacote é lançado no plugin. Como teste do plugin JUnit, para nosso exemplo. O resultado é:

loaderDir = /C:.../ws/plugin/
 localDir = /package/

Aqui podemos obter o caminho absoluto apenas combinando os resultados de ambas as funções. E isso não é suficiente. Entre eles devemos colocar o caminho local do local onde estão os pacotes de classes, relativamente à pasta do plugin. Provavelmente, você terá que inserir algo como srcousrc/test/resource aqui.

Você pode inserir o código no seu e ver os caminhos que possui.

Gangnus
fonte