Como obter o diretório de trabalho atual em Java?

112

Digamos que eu terminei minha aula principal C:\Users\Justian\Documents\. Como posso fazer com que meu programa mostre que está disponível C:\Users\Justian\Documents?

O hard-Coding não é uma opção - ele precisa ser adaptável se for movido para outro local.

Quero despejar vários arquivos CSV em uma pasta, fazer com que o programa reconheça todos os arquivos, depois carregue os dados e os manipule. Eu realmente só quero saber como navegar até essa pasta.

Justian Meyer
fonte
1
dê uma olhada neste artigo .
Matthew J Morrison
1
E se sua classe principal estiver em um arquivo jar? Que tipo de resultado você deseja então?
Mattias Nilsson
1
Por que você precisaria fazer isso de qualquer maneira?
Ed S.
1
Parece que o que você precisa é do diretório em que os arquivos CSV estão e para que o arquivo .jar seja capaz de fazer referência a esse diretório, veja minha resposta se for o caso.
possível duplicata de Getting the Current Working Directory in Java
Kevin

Respostas:

149

Uma maneira seria usar a propriedade do sistema,System.getProperty("user.dir"); que fornecerá "O diretório de trabalho atual quando as propriedades foram inicializadas". Provavelmente é isso que você deseja. para descobrir onde o javacomando foi emitido, no seu caso, no diretório com os arquivos a serem processados, mesmo que o arquivo .jar real possa residir em outro lugar na máquina. Ter o diretório do arquivo .jar real não é útil na maioria dos casos.

O seguinte irá imprimir o diretório atual de onde o comando foi chamado, independentemente de onde o arquivo .class ou .jar o arquivo .class está.

public class Test
{
    public static void main(final String[] args)
    {
        final String dir = System.getProperty("user.dir");
        System.out.println("current dir = " + dir);
    }
}  

se você estiver em /User/me/e seu arquivo .jar contendo o código acima estiver no /opt/some/nested/dir/ comando java -jar /opt/some/nested/dir/test.jar Testserá gerado current dir = /User/me.

Você também deve olhar como bônus em usar um bom analisador de argumentos de linha de comando orientado a objetos. Eu recomendo altamente JSAP , o Java Simple Argument Parser. Isso permitiria que você usasse System.getProperty("user.dir")e, alternativamente, passasse outra coisa para anular o comportamento. Uma solução muito mais sustentável. Isso tornaria a passagem no diretório para o processo muito fácil de fazer e seria capaz de retroceder user.dirse nada fosse passado.


fonte
Vou testar isso quando puder. Estou muito preocupado com esse problema .jar: P
Justian Meyer
você visitou o link em minha resposta a esse problema .jar, onde mostro como construir o arquivo .jar com ANT?
O código do Jarrod que retorna o caminho absoluto do diretório de trabalho atual da propriedade do sistema user.diré muito fácil de usar. System.getProperty ("user.dir");
74

Use CodeSource#getLocation(). Isso também funciona bem em arquivos JAR. Você pode obter CodeSourcepor ProtectionDomain#getCodeSource()e, por ProtectionDomainsua vez, pode ser obtido por Class#getProtectionDomain().

public class Test {
    public static void main(String... args) throws Exception {
        URL location = Test.class.getProtectionDomain().getCodeSource().getLocation();
        System.out.println(location.getFile());
    }
}

Atualizar conforme comentário do OP:

Quero despejar vários arquivos CSV em uma pasta, fazer com que o programa reconheça todos os arquivos, depois carregue os dados e os manipule. Eu realmente só quero saber como navegar até essa pasta.

Isso exigiria codificar / conhecer seu caminho relativo em seu programa. Em vez disso, considere adicionar seu caminho ao caminho de classe para que você possa usarClassLoader#getResource()

File classpathRoot = new File(classLoader.getResource("").getPath());
File[] csvFiles = classpathRoot.listFiles(new FilenameFilter() {
    @Override public boolean accept(File dir, String name) {
        return name.endsWith(".csv");
    }
});

Ou para passar seu caminho como main()argumento.

BalusC
fonte
3
+1. Existem várias condições para fazer este trabalho; o mais importante é que sua "classe principal" seja carregada do sistema de arquivos. Em Java, não é muito incomum que essa suposição seja falsa. Mas, se você tiver certeza de que está carregando sua classe de um JAR no sistema de arquivos, este é o método que funciona.
erickson
Tudo depende, realmente. Estou tentando fazer meu JAR compilar, mas isso é um problema separado no momento. Se você acha que pode ajudar com isso, verifique: stackoverflow.com/questions/3152240/… . Tenho certeza de que postar isso é algum tipo de infração, mas está relacionado a esse problema. Se eu conseguir consertar isso, com certeza essa será a minha resposta.
Justian Meyer
Por que eu precisaria codificar isso? Já fiz coisas semelhantes antes. Suponha que meu jar e minha pasta sempre terão um relacionamento semelhante (ou seja, no mesmo diretório). Se isso fosse verdade, eu poderia obter o diretório do jar e modificá-lo para localizar a pasta.
Justian Meyer
Se estiver na mesma pasta do arquivo JAR, então já está no caminho de classe. A palavra "hardcoding" é um pouco exagerada. Na verdade, eu quis dizer "conhecer seu caminho em relação ao arquivo JAR".
BalusC
1
@Moebius: Hein? Você é novo no Java? Verifique o javadoc . Basta usar exatamente aquele retornado pelo getLocation()método. Outros obviamente não vão funcionar.
BalusC 01 de
31
File currentDirectory = new File(new File(".").getAbsolutePath());
System.out.println(currentDirectory.getCanonicalPath());
System.out.println(currentDirectory.getAbsolutePath());

Imprime algo como:

/path/to/current/directory
/path/to/current/directory/.

Observe que File.getCanonicalPath()lança uma IOException marcada, mas removerá coisas como ../../../

ciber-monge
fonte
13
this.getClass().getClassLoader().getResource("").getPath()
Peter De Winter
fonte
observe que isso retornará o caminho para "bin / classes /", e não apenas "bin".
desenvolvedor Android
ao depurar um aplicativo em execução usando o Intellij Idea, ele retornou "/C:/Program%20Files/Java/jdk1.8.0_112/:"
velocidade
5

Acabei de usar:

import java.nio.file.Path;
import java.nio.file.Paths;

...

Path workingDirectory=Paths.get(".").toAbsolutePath();
user3696181
fonte
9
O seu não está funcionando, este está corretoPaths.get("").toAbsolutePath();
Para Kra
@ToKra Se eu fizer Paths.get("my/file").toAbsolutePath()isso /my/file, o que definitivamente não é o cwd.
abergmeier
1
@abergmeier eu escrevi "" na string, não "meu / arquivo"
Para Kra,
5

Se você deseja obter seu diretório de trabalho atual, use a seguinte linha

System.out.println(new File("").getAbsolutePath());
rjrajsaha
fonte
4

Se você quiser o caminho absoluto do código-fonte atual, minha sugestão é:

String internalPath = this.getClass().getName().replace(".", File.separator);
String externalPath = System.getProperty("user.dir")+File.separator+"src";
String workDir = externalPath+File.separator+internalPath.substring(0, internalPath.lastIndexOf(File.separator));
jmamatos
fonte
Isso não funciona quando você executa em um IDE ou usa algo para girar a instância.
Sarp Kaya,
O caminho interno é java \ lang \ Class O caminho externo é E: \ BranchProduction1.4.0 \ FilesTestProject \ src O diretório de trabalho é E: \ BranchProduction1.4.0 \ FilesTestProject \ src \ java \ lang você poderia explicar a saída?
JAVA
3

Quem disse que sua classe principal está em um arquivo em um disco rígido local? As classes são mais frequentemente agrupadas em arquivos JAR e, às vezes, carregadas pela rede ou mesmo geradas instantaneamente.

Então, o que você realmente deseja fazer? Provavelmente existe uma maneira de fazer isso que não faz suposições sobre a origem das classes.

Michael Borgwardt
fonte
Quero despejar vários arquivos CSV em uma pasta, fazer com que o programa reconheça todos os arquivos, depois carregue os dados e os manipule. Realmente, só quero saber como navegar até essa pasta.
Justian Meyer
Talvez eu esteja faltando alguma coisa, mas parece que um caminho absoluto funcionaria. Você disse que não pode codificá-lo, mas como saberá qual pasta procurar para começar?
Chris Thompson
Bem, o problema é que quero levá-lo para outros computadores, não apenas para o meu. Não vejo como o caminho seria codificado. "Suponha que meu jar e minha pasta sempre terão um relacionamento semelhante (ou seja, no mesmo diretório). Se isso fosse verdade, eu poderia obter o diretório do jar e modificá-lo para localizar a pasta." A única maneira de codificar seria se não precisasse incluir o caminho completo do disco rígido para o arquivo. Talvez eu possa voltar apenas 3 pastas (ou seja, "Documents \ Project \ Dump \ [arquivo / pasta]")
Justian Meyer
Eu diria que o que você deseja fazer é obter um identificador para o diretório em que o arquivo jar reside. Isso atenderia aos seus requisitos?
Chris Thompson