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


1029

Quero acessar meu diretório de trabalho atual usando java.

Meu código:

 String current = new java.io.File( "." ).getCanonicalPath();
        System.out.println("Current dir:"+current);
 String currentDir = System.getProperty("user.dir");
        System.out.println("Current dir using System:" +currentDir);

Resultado:

Current dir: C:\WINDOWS\system32
Current dir using System: C:\WINDOWS\system32

Minha saída não está correta porque a unidade C não é meu diretório atual.

Como obter o diretório atual?


2
você pode colar aqui o que vê quando executa o cdcomando no prompt de comando ao executar isso?
— Nishant 02/02

3
O que você está tentando realizar acessando o diretório de trabalho? Isso poderia ser feito usando o caminho da classe? Por exemplo, se você precisar ler um arquivo de texto no sistema de arquivos, poderá encontrá-lo facilmente quando estiver no caminho da classe.
— earldouglas

1
como? Você poderia elaborar por favor?
— Gráficos C

1
Para obter algumas informações sobre como acessar um arquivo no caminho da classe, consulte stackoverflow.com/questions/1464291/…
— downeyt

7
Para fins de depuração, o diretório de trabalho pode ser útil para saber se o programa parece não conseguir acessar os arquivos existentes.
— Nsandersen

Respostas:


1152
public class JavaApplication {
  public static void main(String[] args) {
       System.out.println("Working Directory = " + System.getProperty("user.dir"));
  }
}

Isso imprimirá um caminho absoluto completo de onde seu aplicativo foi inicializado.


A partir da documentação :

java.iopacote resolve nomes de caminho relativos usando o diretório de usuário atual. O diretório atual é representado como propriedade do sistema, ou seja, user.dire é o diretório de onde a JVM foi chamada.


25
@ubuntudroid: é por isso que mencionei especificamente que ele imprimirá o caminho de onde o aplicativo foi inicializado. Meu palpite é que o iniciador de threads execute diretamente o jar / programa após iniciar o prompt do commnad (que é basicamente em C: \ WINDOWS \ system32). Espero que você entenda meu argumento. Supondo que você tenha votado mal, saiba que pelo menos você se importou em deixar uma resposta. :)
— Anuj Patel

1
user.dir obterá o caminho para a pasta em que o processo foi iniciado. Para obter o caminho real para a pasta principal do aplicativo, veja minha resposta abaixo.
— Peter De Winter

1
Quero dizer "todo o código que depende dele para encontrar o diretório atual falha". Nem todo o código em geral. (Eu era lento para editar o comentário original)
— Suboptimal

13
@SubOptimal se o usuário configurou -Duser.dir, é possível que ele queira executar isso no diretório de trabalho personalizado.
— barwnikk

5
@indyaah De fato, esta resposta está errada, há uma diferença sutil entre um diretório de trabalho do usuário e um diretório de trabalho atual de um processo do sistema (cwd); na maioria das vezes o "user.dir" aponta para o código de um processo (java); mas "user.dir" possui semântica diferente e não deve ser usado para obter o cwd de um processo java; btw: há mais imóveis à java processo docs.oracle.com/javase/tutorial/essential/environment/... apenas para referência
— comeGetSome

382

Consulte: http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html

Usando java.nio.file.Pathe java.nio.file.Paths, você pode fazer o seguinte para mostrar o que Java acha que é o seu caminho atual. Isso para 7 em diante e usa o NIO.

Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current relative path is: " + s);

Isso Current relative path is: /Users/george/NetBeansProjects/Tutorialsmostra que, no meu caso, é de onde eu executei a classe. Construir caminhos de maneira relativa, ao não usar um separador à esquerda para indicar que você está construindo um caminho absoluto, usará esse caminho relativo como ponto de partida.


2
O primeiro não foi verificado, mas o segundo realmente receberá sua pasta pessoal. Não é o diretório de trabalho atual no qual o aplicativo está sendo executado.
— Peter De Winter

12
Não confunda o diretório inicial do usuário ("user.home", / Users / george no seu caso) e o diretório ativo atual ("user.dir", que será o diretório a partir do qual você iniciou a JVM para seu aplicativo , pode ser algo como, por exemplo, / Users / george / workspace / FooBarProject).
— David

1
Eu prefiro assim. Quando eu preciso do pai do diretório de trabalho, isso não funciona Paths.get("").getParent():, ele fornece null. Em vez isso funciona: Paths.get("").toAbsolutePath().getParent().
— Ole VV

235

O seguinte funciona no Java 7 e superior (veja aqui para documentação).

import java.nio.file.Paths;

Paths.get(".").toAbsolutePath().normalize().toString();

11
Como isso é melhor do que o mais portátil import java.io.File; File(".").getAbsolutePath()?
— Evgeni Sergeev

8
Quando você diz portátil, quer dizer que funciona em Java 6 e versões anteriores? Paths.get()pode ser considerado melhor, pois fornece acesso direto à Pathinterface mais poderosa .
— Ole VV

8
Qual é a vantagem potencial de usar .normalize()neste contexto?
— Ole VV

7
@ OleV.V. De Javadoc: ( método normalizar )Returns a path that is this path with redundant name elements eliminated.
— Stephan

Já seria normalizado neste caso.
— JM Becker

73

Isso fornecerá o caminho do seu diretório de trabalho atual:

Path path = FileSystems.getDefault().getPath(".");

E isso lhe dará o caminho para um arquivo chamado "Foo.txt" no diretório de trabalho:

Path path = FileSystems.getDefault().getPath("Foo.txt");

Edit: Para obter um caminho absoluto do diretório atual:

Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();

* Atualização * Para obter o diretório de trabalho atual:

Path path = FileSystems.getDefault().getPath("").toAbsolutePath();

11
isso apenas retorna '.' para mim.
— John ktejik

3
Sim, em muitos sistemas que serão a referência ao diretório de trabalho. Para obter o caminho absoluto você pode adicionar mais uma chamada de métodoPath path = FileSystems.getDefault().getPath(".").toAbsolutePath();
— Mark

2
Você não precisa do foo.txt, basta colocar em uma cadeia vazia para obter o diretório
— john ktejik

1
No Windows (10), isso apenas me fornece um Pathobjeto apontando para um arquivo chamado .dentro do diretório de trabalho atual. Usando uma string vazia, em vez de "."funcionar para mim.
— Kröw 18/04/19

36

Esta é a solução para mim

File currentDir = new File("");

1
Isto tem efeitos colaterais quando você usa tal objeto um arquivo como um pai de outro arquivo: new File (new File ( ""), "subdir") não funcionará como esperado
— MRalwasser

13
Para corrigir isso, use em new File("").getAbsoluteFile()vez disso.
— MRalwasser

4
Pelo que vale, tive mais sorte com o File (".").
— precisa saber é o seguinte

Como definir um caminho relativo em Java Esta página me ajudou. Também assumi que deveria usar /ao criar um caminho relativo. Eu estava errado, não comece /. ../também funciona para subir na árvore de diretórios.
— precisa

@keshlam Isso me deu um arquivo no diretório atual chamado ..
— Kröw 2/06/19

32

Encontrei esta solução nos comentários, melhor do que outros e mais portátil:

String cwd = new File("").getAbsolutePath();

Ou até

String cwd = Paths.get("").toAbsolutePath();

Isso é exatamente o mesmo que a resposta de comeGetSome e é realmente o caminho Java <7
— GoGoris 03/01

30

O que faz você pensar que c: \ windows \ system32 não é seu diretório atual? A user.dirpropriedade deve ser explicitamente "Diretório de trabalho atual do usuário".

Em outras palavras, a menos que você inicie o Java na linha de comando, c: \ windows \ system32 provavelmente é o seu CWD. Ou seja, se você clicar duas vezes para iniciar o programa, é improvável que o CWD seja o diretório em que você está clicando duas vezes.

Editar : parece que isso só é verdade para janelas antigas e / ou versões Java.


2
Isso não parece ser verdade, pelo menos não na minha máquina Windows 7 usando Java 7. user.diré sempre a pasta em que cliquei duas vezes no arquivo jar.
— Jolta

26

Use CodeSource#getLocation().

Isso funciona bem em arquivos JAR também. 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());
    }
}

2
Isso retorna o local do arquivo JAR. Não foi o que foi pedido.
— Marquês de Lorne #

22
this.getClass().getClassLoader().getResource("").getPath()

12
Lança um NPE quando inicio meu aplicativo a partir de um arquivo JAR clicando duas vezes nele.
— Matthew Wise

2
Isso retorna ""se o aplicativo estiver sendo executado a partir de um arquivo JAR ou um elemento CLASSPATH. Não foi o que foi pedido.
— Marquês de Lorne #

@ Zizouz212 getClass()é um método de objeto, portanto, em um contexto estático, apenas remover o thisnão funciona. Você teria que se referir explicitamente à classe em que está participando MyClass.class.getClassLoader()......
— Kröw 2/06/19

No entanto, ele não retornará o diretório de trabalho ...
— Angel O'Sphere 14/10

18

geralmente, como um objeto File:

File getCwd() {
  return new File("").getAbsoluteFile();
}

você pode querer ter uma sequência completa qualificada como "D: / a / b / c", fazendo:

getCwd().getAbsolutePath()

1
Isso funciona bem nos testes do Android, pois o Android não inclui java.nio.file.Files.
— Iamreptar # 29/15

Parece não funcionar para mim em um contexto estático (o novo arquivo ("") lança NullPointerException)) ..?
— Nsandersen

2
@nsandersen você provavelmente usou um objeto File errado: System.out.println (new java.io.File (""). getAbsolutePath ());
— comeGetSome


5

No Linux, quando você executa um arquivo jar no terminal , ambos retornam o mesmo String: "/ home / CurrentUser" , não importa onde esteja o arquivo jar. Depende apenas do diretório atual que você está usando com o seu terminal, quando inicia o arquivo jar.

Paths.get("").toAbsolutePath().toString();

System.getProperty("user.dir");

Se o seu Classcom mainseria chamado MainClass, então tente:

MainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile();

Isso retornará um Stringcom caminho absoluto do arquivo jar .


3
O que não foi solicitado.
— Marquês de Lorne #

5

O uso do Windows user.dir retorna o diretório conforme o esperado, mas NÃO quando você inicia o aplicativo com direitos elevados (executado como admin); nesse caso, você obtém C: \ WINDOWS \ system32


3

Espero que você queira acessar o diretório atual, incluindo o pacote, ou seja, se o seu programa Java estiver presente c:\myApp\com\foo\src\service\MyTest.javae você desejar imprimir até c:\myApp\com\foo\src\serviceentão, tente o seguinte código:

String myCurrentDir = System.getProperty("user.dir")
            + File.separator
            + System.getProperty("sun.java.command")
                    .substring(0, System.getProperty("sun.java.command").lastIndexOf("."))
                    .replace(".", File.separator);
    System.out.println(myCurrentDir);

Nota: Este código é testado apenas no Windows com Oracle JRE.


6
Seria um desserviço não rebaixar esta resposta. Por favor, pense com mais cuidado antes de postar. Seu código está quebrado, a menos que tudo isso seja verdadeiro: 1. o JRE é do Oracle, caso contrário, não haverá nenhuma propriedade do sistema "sun.java.command" → NPE; 2. o sistema operacional é Windows (use em File.separatorvez disso, ou um Fileconstrutor de vários argumentos ); 3. o caminho da classe é especificado na linha de comando e o 'diretório atual incluindo o pacote' (??) é: a. especificado primeiro, b. especificado absolutamente, c. corresponde exatamente ao CWD (mesmo com a distinção entre maiúsculas e minúsculas do Windows) e d. é um descendente do CWD
— Michael Scheper

Isso aborda os pontos 1 e 2. Mas, a menos que esteja faltando alguma coisa, você ainda está confiando no caminho de classe sendo especificado na linha de comando (ou seja, não em uma variável de ambiente) e no 'diretório atual, incluindo o pacote' (I admita que realmente não entendo o que você quer dizer com isso) ser um descendente especificamente do primeiro elemento no caminho de classe. E o problema de correspondência de casos permanece. Sinto muito se meu comentário não foi útil; Eu sacrifiquei a clareza para manter o limite de caracteres do comentário.
— Michael Scheper

@ Inversus, apenas "funciona perfeitamente" em alguns ambientes; por acaso você teve a sorte de testá-lo em alguns. Escrever software que falha em ambientes de tempo de execução legítimos não é uma boa prática, mesmo quando seu conjunto de ambientes de teste não é amplo o suficiente para incluí-los.
— Charles Duffy

@CharlesDuffy Você está certo, isso não é uma boa prática. Felizmente, essa solução "solucionando meu problema específico" não fez com que "falhasse em ambientes de tempo de execução legítimos". De fato, isso me ajudou a resolver essa falha e a escrever um código mais robusto, além de resolver o problema muito específico que eu tinha (que estava apenas um pouco relacionado a essa pergunta / resposta). Acho que tive a sorte de encontrá-lo.
— Inversus

3

Mencione que ele está marcado apenas Windowsmas acho que funciona perfeitamente em outros sistemas operacionais [ Linux,MacOs,Solaris] :).


Eu tinha 2 .jar arquivos no mesmo diretório. Eu queria que um .jararquivo iniciasse o outro .jararquivo que está no mesmo diretório.

O problema é que, quando você o inicia cmdno diretório atual, é system32.


Advertências!

  • O abaixo parece funcionar muito bem em todos os testes que fiz, mesmo com o nome da pasta ;][[;'57f2g34g87-8+9-09!2#@!$%^^&()ou ()%&$%^@# funciona bem.
  • Estou usando o ProcessBuildercom o seguinte, como a seguir:

🍂 ..

//The class from which i called this was the class `Main`
String path = getBasePathForClass(Main.class);
String applicationPath=  new File(path + "application.jar").getAbsolutePath();


System.out.println("Directory Path is : "+applicationPath);

//Your know try catch here
//Mention that sometimes it doesn't work for example with folder `;][[;'57f2g34g87-8+9-09!2#@!$%^^&()` 
ProcessBuilder builder = new ProcessBuilder("java", "-jar", applicationPath);
builder.redirectErrorStream(true);
Process process = builder.start();

//...code

🍂 getBasePathForClass(Class<?> classs):

    /**
     * Returns the absolute path of the current directory in which the given
     * class
     * file is.
     * 
     * @param classs
     * @return The absolute path of the current directory in which the class
     *         file is.
     * @author GOXR3PLUS[StackOverFlow user] + bachden [StackOverFlow user]
     */
    public static final String getBasePathForClass(Class<?> classs) {

        // Local variables
        File file;
        String basePath = "";
        boolean failed = false;

        // Let's give a first try
        try {
            file = new File(classs.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());

            if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
                basePath = file.getParent();
            } else {
                basePath = file.getPath();
            }
        } catch (URISyntaxException ex) {
            failed = true;
            Logger.getLogger(classs.getName()).log(Level.WARNING,
                    "Cannot firgue out base path for class with way (1): ", ex);
        }

        // The above failed?
        if (failed) {
            try {
                file = new File(classs.getClassLoader().getResource("").toURI().getPath());
                basePath = file.getAbsolutePath();

                // the below is for testing purposes...
                // starts with File.separator?
                // String l = local.replaceFirst("[" + File.separator +
                // "/\\\\]", "")
            } catch (URISyntaxException ex) {
                Logger.getLogger(classs.getName()).log(Level.WARNING,
                        "Cannot firgue out base path for class with way (2): ", ex);
            }
        }

        // fix to run inside eclipse
        if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
                || basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
            basePath = basePath.substring(0, basePath.length() - 4);
        }
        // fix to run inside netbeans
        if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
            basePath = basePath.substring(0, basePath.length() - 14);
        }
        // end fix
        if (!basePath.endsWith(File.separator)) {
            basePath = basePath + File.separator;
        }
        return basePath;
    }

Isso retorna o local do arquivo JAR. Não foi o que foi pedido.
— Marquês de Lorne #

@EJP A localização do arquivo .jar não é o diretório de trabalho atual do programa java?
— GOXR3PLUS

2

O diretório de trabalho atual é definido de maneira diferente em diferentes implementações Java. Para determinadas versões anteriores ao Java 7, não havia uma maneira consistente de obter o diretório de trabalho. Você pode contornar isso iniciando o arquivo Java -De definindo uma variável para conter as informações

Algo como

java -D com.mycompany.workingDir="%0"

Isso não está certo, mas você entendeu. Então System.getProperty("com.mycompany.workingDir")...


6
Não é relevante para a pergunta.
— Peter De Winter

1
Ele tem um significado para Java - é o local no disco em que os arquivos que você abre com nomes de caminho relativos são relativos.
— Rob I

2
Sim, tem um significado. Minhas palavras foram um pouco mal escolhidas. Mas você perder o ponto - antes de Java 7 não havia nenhuma maneira de saber o diretório de trabalho atual, e diferentes implementações defini-los ... diferente ...
— MJB

1

suponha que você esteja tentando executar seu projeto dentro do eclipse ou netbean ou independente da linha de comando. Eu escrevi um método para corrigi-lo

public static final String getBasePathForClass(Class<?> clazz) {
    File file;
    try {
        String basePath = null;
        file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
        if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
            basePath = file.getParent();
        } else {
            basePath = file.getPath();
        }
        // fix to run inside eclipse
        if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
                || basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
            basePath = basePath.substring(0, basePath.length() - 4);
        }
        // fix to run inside netbean
        if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
            basePath = basePath.substring(0, basePath.length() - 14);
        }
        // end fix
        if (!basePath.endsWith(File.separator)) {
            basePath = basePath + File.separator;
        }
        return basePath;
    } catch (URISyntaxException e) {
        throw new RuntimeException("Cannot firgue out base path for class: " + clazz.getName());
    }
}

Para usar, em qualquer lugar que você deseja obter o caminho base para ler o arquivo, você pode passar sua classe âncora para o método acima, o resultado pode ser o que você precisa: D

melhor,


2
Isso retorna o local do arquivo JAR. Não foi o que foi pedido.
— Marquês de Lorne #

@ user207421 sim, eu sei que esta resposta não é a resposta verdadeira para a pergunta, mas na maioria das vezes, todos desejam obter o "diretório onde os frascos localizados" em vez de "diretório de trabalho da linha de comando".
— bachden

0

Nenhuma das respostas postadas aqui funcionou para mim. Aqui está o que funcionou:

java.nio.file.Paths.get(
  getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
);

Edit: A versão final no meu código:

URL myURL = getClass().getProtectionDomain().getCodeSource().getLocation();
java.net.URI myURI = null;
try {
    myURI = myURL.toURI();
} catch (URISyntaxException e1) 
{}
return java.nio.file.Paths.get(myURI).toFile().toString()

Isso retorna o local do arquivo JAR. Não foi o que foi pedido.
— Marquês de Lorne #

0

Esta é a minha bala de prata sempre que surge o momento de confusão. (Chame como a primeira coisa em geral). Talvez, por exemplo, a JVM tenha sido desviada para uma versão diferente pelo IDE. Essa função estática pesquisa o PID do processo atual e abre o VisualVM nesse pid. A confusão acaba aí porque você quer tudo e consegue ...

  public static void callJVisualVM() {
    System.out.println("USER:DIR!:" + System.getProperty("user.dir"));
    //next search current jdk/jre
    String jre_root = null;
    String start = "vir";
    try {
        java.lang.management.RuntimeMXBean runtime =
                java.lang.management.ManagementFactory.getRuntimeMXBean();
        String jvmName = runtime.getName();
        System.out.println("JVM Name = " + jvmName);
        long pid = Long.valueOf(jvmName.split("@")[0]);
        System.out.println("JVM PID  = " + pid);
        Runtime thisRun = Runtime.getRuntime();
        jre_root = System.getProperty("java.home");
        System.out.println("jre_root:" + jre_root);
        start = jre_root.concat("\\..\\bin\\jvisualvm.exe " + "--openpid " + pid);
        thisRun.exec(start);
    } catch (Exception e) {
        System.getProperties().list(System.out);
        e.printStackTrace();
    }
}


-7

este é o nome do diretório atual

String path="/home/prasad/Desktop/folderName";
File folder = new File(path);
String folderName=folder.getAbsoluteFile().getName();

este é o caminho do diretório atual

String path=folder.getPath();

1
O OP queria o diretório de trabalho atual de onde o aplicativo foi executado.
— Leif Gruenwoldt 5/11

Este é o seu diretório pessoal, não o diretório de trabalho atual de ninguém, exceto talvez o seu. Não foi o que foi pedido.
— Marquês de Lorne
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.