¿Cómo obtener el directorio de trabajo actual en Java?

1029

Quiero acceder a mi directorio de trabajo actual usando java.

Mi 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);

Salida:

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

Mi salida no es correcta porque la unidad C no es mi directorio actual.

¿Cómo obtener el directorio actual?

Qazi
fuente
2
¿Puedes pegar aquí lo que ves cuando ejecutas el cdcomando en tu símbolo del sistema cuando ejecutas esto?
Nishant
3
¿Qué es lo que estás tratando de lograr accediendo al directorio de trabajo? ¿Podría hacerse utilizando la ruta de clase en su lugar? Por ejemplo, si necesita leer un archivo de texto en el sistema de archivos, puede encontrarlo fácilmente cuando está en la ruta de clase.
Earldouglas
1
¿cómo? ¿Podría elaborar por favor?
Gráficos C
1
Para obtener información sobre cómo acceder a un archivo en la ruta de clase, consulte stackoverflow.com/questions/1464291/…
downeyt
77
Para fines de depuración, el directorio de trabajo podría ser útil para saber si el programa no parece poder acceder a los archivos que existen.
nsandersen

Respuestas:

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

Esto imprimirá una ruta absoluta completa desde donde se inicializó su aplicación.


De la documentación :

java.ioEl paquete resuelve los nombres de ruta relativos utilizando el directorio de usuario actual. El directorio actual se representa como propiedad del sistema, es decir, user.diry es el directorio desde el que se invocó la JVM.

Anuj Patel
fuente
25
@ubuntudroid: por eso mencioné específicamente que imprimirá la ruta desde donde se inicializó la aplicación. Supongo que el iniciador de subprocesos ejecuta directamente el jar / programa después de iniciar el símbolo del sistema (que está básicamente en C: \ WINDOWS \ system32). Espero que entiendas mi punto. Asumiendo que has votado mal, aprecia que al menos te haya importado dejar una respuesta. :)
Anuj Patel
1
user.dir obtendrá la ruta a la carpeta donde se inició el proceso. Para obtener la ruta real a la carpeta principal de la aplicación, vea mi respuesta a continuación.
Peter De Winter
1
Quiero decir "todo el código que se basa en él para encontrar el directorio actual falla". No todo el código en general. (Era lento para editar el comentario original)
SubOptimal
13
@SubOptimal si el usuario configuró -Duser.dir, es probable que quiera ejecutar esto en un directorio de trabajo personalizado.
barwnikk
55
@indyaah de hecho, esta respuesta es incorrecta, hay una sutil diferencia entre un directorio de trabajo del usuario y un directorio de trabajo actual de un proceso del sistema (cwd); la mayoría de las veces el "user.dir" apunta al cwd de un proceso (java); pero "user.dir" tiene una semántica diferente y no se utilizará para obtener el cwd de un proceso java; por cierto: hay más propiedades disponibles para el proceso java docs.oracle.com/javase/tutorial/essential/environment/… solo como referencia
comeGetSome
382

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

Usando java.nio.file.Pathy java.nio.file.Paths, puede hacer lo siguiente para mostrar lo que Java cree que es su ruta actual. Esto para 7 y más, y usa NIO.

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

Esto da como resultado Current relative path is: /Users/george/NetBeansProjects/Tutorialsque en mi caso es donde ejecuté la clase. Al construir rutas de forma relativa, al no utilizar un separador inicial para indicar que está construyendo una ruta absoluta, utilizará esta ruta relativa como punto de partida.

geoO
fuente
2
El primero no se ha verificado, pero el segundo realmente obtendrá su carpeta de inicio. No es el directorio de trabajo actual en el que se ejecuta la aplicación.
Peter De Winter
12
No confunda el directorio de inicio del usuario ("user.home", / Users / george en su caso) y el directorio de trabajo actual ("user.dir", que será el directorio desde el que inició la JVM para su aplicación , por lo que podría ser algo como, por ejemplo, / Users / george / workspace / FooBarProject).
David
1
Prefiero de esta manera Cuando necesito el padre del directorio de trabajo, esto no funciona: Paths.get("").getParent()da null. En cambio, esta funciona: Paths.get("").toAbsolutePath().getParent().
Ole VV
235

Lo siguiente funciona en Java 7 y versiones posteriores (consulte aquí la documentación).

import java.nio.file.Paths;

Paths.get(".").toAbsolutePath().normalize().toString();
Dmitry Bespalov
fuente
11
¿Cómo es esto mejor que el más portátil import java.io.File; File(".").getAbsolutePath()?
Evgeni Sergeev
8
Cuando dice portátil, ¿quiere decir que funciona en Java 6 y versiones anteriores? Paths.get()puede considerarse mejor porque da acceso directo a la Pathinterfaz más potente .
Ole VV
8
¿Cuál es la ventaja potencial de usar .normalize()en este contexto?
Ole VV
77
@ OleV.V. Desde Javadoc: ( método normalizar )Returns a path that is this path with redundant name elements eliminated.
Stephan
Ya estaría normalizado en este caso.
JM Becker
73

Esto le dará la ruta de su directorio de trabajo actual:

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

Y esto le dará la ruta a un archivo llamado "Foo.txt" en el directorio de trabajo:

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

Editar: para obtener una ruta absoluta del directorio actual:

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

* Actualización * Para obtener el directorio de trabajo actual:

Path path = FileSystems.getDefault().getPath("").toAbsolutePath();
marca
fuente
11
esto solo devuelve '.' para mi.
John Ktejik 01 de
3
Sí, en muchos sistemas será la referencia al directorio de trabajo. Para obtener la ruta absoluta, puede agregar una llamada de método másPath path = FileSystems.getDefault().getPath(".").toAbsolutePath();
Marque
2
No necesita el foo.txt, solo coloque una cadena vacía para obtener el directorio
john ktejik
1
En Windows (10) esto solo me da un Pathobjeto que apunta a un archivo llamado .dentro del directorio de trabajo actual. Usando una cadena vacía, en lugar de "."trabajar para mí.
Kröw
36

Esta es la solución para mi

File currentDir = new File("");
usuario2430452
fuente
1
Esto tiene efectos secundarios cuando usa un objeto de archivo como padre de otro archivo: el nuevo archivo (nuevo archivo (""), "subdir") no funcionará como se esperaba
MRalwasser
13
Para solucionar esto, use new File("").getAbsoluteFile()en su lugar.
MRalwasser
44
Por lo que vale, tuve mejor suerte con File (".").
keshlam
Cómo definir una ruta relativa en Java Esta página me ayudó. También supuse que debería usar /al crear una ruta relativa. Me equivoqué, no empieces con /. ../También funciona para subir en el árbol de directorios.
Irrationalkilla
@keshlam Eso me dio un archivo en el directorio actual llamado ..
Kröw
32

He encontrado esta solución en los comentarios que es mejor que otros y más portátil:

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

O incluso

String cwd = Paths.get("").toAbsolutePath();
freedev
fuente
Esto es exactamente lo mismo que la respuesta de comeGetSome y en realidad es Java <7 way
GoGoris
30

¿Qué te hace pensar que c: \ windows \ system32 no es tu directorio actual? La user.dirpropiedad es explícitamente "Directorio de trabajo actual del usuario".

Para decirlo de otra manera, a menos que inicie Java desde la línea de comandos, c: \ windows \ system32 probablemente sea su CWD. Es decir, si hace doble clic para iniciar su programa, es poco probable que el CWD sea el directorio desde el que hace doble clic.

Editar : Parece que esto solo es cierto para ventanas antiguas y / o versiones de Java.

Paul Wagland
fuente
2
Esto no parece ser cierto, al menos no en mi máquina con Windows 7 que usa Java 7. user.dires consistentemente la carpeta donde hice doble clic en el archivo jar.
Jolta
26

Uso CodeSource#getLocation().

Esto también funciona bien en archivos JAR. Puede obtener CodeSourcepor ProtectionDomain#getCodeSource()y ProtectionDomaina su vez puede obtener 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());
    }
}
Bigoloo
fuente
2
Esto devuelve la ubicación del archivo JAR. No es lo que se pidió.
Marqués de Lorne
22
this.getClass().getClassLoader().getResource("").getPath()
Peter De Winter
fuente
12
Lanza un NPE cuando inicio mi aplicación desde un archivo JAR haciendo doble clic en él.
Matthew Wise el
2
Esto se devuelve ""si la aplicación se ejecuta desde un archivo JAR o un elemento CLASSPATH. No es lo que se pidió.
Marqués de Lorne
@ Zizouz212 getClass()es un método de objeto, por lo que en un contexto estático solo eliminar el thisno funciona. Tendrías que hacer referencia explícita a la clase en la que estás haciendo MyClass.class.getClassLoader()......
Kröw
Sin embargo, no devolverá el directorio de trabajo ...
Angel O'Sphere
18

generalmente, como un objeto File:

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

es posible que desee tener una cadena completa calificada como "D: / a / b / c" haciendo:

getCwd().getAbsolutePath()
comeGetSome
fuente
1
Esto funciona bien en las pruebas de Android ya que Android no incluye java.nio.file.Files.
iamreptar
No parece funcionar para mí en un contexto estático (nuevo archivo ("") arroja NullPointerException) ...?
nsandersen
2
@nsandersen probablemente haya usado un objeto de archivo incorrecto: System.out.println (new java.io.File (""). getAbsolutePath ());
comeGetSome
5

En Linux cuando ejecuta un archivo jar desde la terminal , ambos devolverán lo mismo String: "/ home / CurrentUser" , sin importar dónde se encuentre su archivo jar. Depende de qué directorio actual esté utilizando con su terminal, cuando inicie el archivo jar.

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

System.getProperty("user.dir");

Si su Classcon mainque se llamaría MainClass, a continuación, tratar:

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

Esto devolverá una Stringcon ruta absoluta del frasco de archivo.

Jan Povolný
fuente
3
Que no es lo que se pidió.
Marqués de Lorne
5

El uso de Windows user.dir devuelve el directorio como se esperaba, pero NO cuando inicia su aplicación con derechos elevados (se ejecuta como administrador), en ese caso obtiene C: \ WINDOWS \ system32

SijeDeHaan
fuente
3

Espero que desee acceder al directorio actual, incluido el paquete, es decir, si su programa Java está en c:\myApp\com\foo\src\service\MyTest.javaejecución y desea imprimir hasta c:\myApp\com\foo\src\serviceentonces, puede probar el siguiente 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 solo se prueba en Windows con Oracle JRE.

JSS
fuente
66
Sería perjudicial no rechazar esta respuesta. Por favor, piense más cuidadosamente antes de publicar. Su código está roto, a menos que todo esto sea cierto: 1. el JRE es de Oracle, de lo contrario no habrá propiedad del sistema "sun.java.command" → NPE; 2. el sistema operativo es Windows (Use en su File.separatorlugar, o un Fileconstructor de argumentos múltiples ); 3. el classpath se especifica en la línea de comando, y el 'directorio actual que incluye el paquete' (??) es: a. especificado primero, b. especificado absolutamente, c. coincide exactamente con la CWD (incluso con la insensibilidad a mayúsculas y minúsculas de Windows), y d. es un descendiente de la CWD
Michael Scheper
Eso aborda los puntos 1 y 2. Pero a menos que me falte algo, usted todavía depende de la ruta de clase que se especifica en la línea de comando (es decir, no en una variable de entorno), y para el 'directorio actual que incluye el paquete' (I admito que realmente no entiendo lo que quieres decir con eso) ser descendiente de específicamente el primer elemento en el classpath. Y el problema de coincidencia de casos persiste. Lo siento si mi comentario no fue útil; Sacrifiqué la claridad para mantenerme dentro del límite de caracteres de comentario.
Michael Scheper
@Inversus, solo "funciona perfectamente" en algunos entornos; Tuviste la suerte de probarlo en tal. Escribir software que falla en entornos legítimos de tiempo de ejecución no es una buena práctica, incluso cuando su conjunto de entornos de prueba no es lo suficientemente extenso como para incluirlos.
Charles Duffy
@CharlesDuffy Tienes razón, esa no es una buena práctica. Afortunadamente, esta solución "resolvió mi problema específico" no lo hizo "[fallar] en entornos legítimos de tiempo de ejecución". De hecho, me ayudó a resolver tal falla y escribir un código más robusto, además de resolver el problema muy específico que tenía (que solo estaba algo relacionado con esta pregunta / respuesta). Supongo que tuve la suerte de encontrarlo.
Inversus
3

Mencione que solo está registrado Windowspero creo que funciona perfectamente en otros sistemas operativos [ Linux,MacOs,Solaris] :).


Tenía 2 .jar archivos en el mismo directorio. Quería que desde un .jararchivo comenzara el otro .jararchivo que está en el mismo directorio.

El problema es que cuando lo inicia desde el cmddirectorio actual es system32.


Advertencias!

  • Lo siguiente parece funcionar bastante bien en todas las pruebas que he hecho incluso con el nombre de la carpeta ;][[;'57f2g34g87-8+9-09!2#@!$%^^&()o ()%&$%^@# funciona bien.
  • Estoy usando ProcessBuilderel siguiente a continuación:

🍂 ..

//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;
    }
GOXR3PLUS
fuente
Esto devuelve la ubicación del archivo JAR. No es lo que se pidió.
Marqués de Lorne
@EJP ¿La ubicación del archivo .jar no es el directorio de trabajo actual del programa java?
GOXR3PLUS
2

El directorio de trabajo actual se define de manera diferente en diferentes implementaciones de Java. Para ciertas versiones anteriores a Java 7 no había una forma consistente de obtener el directorio de trabajo. Podría solucionar este problema iniciando un archivo Java -Dy definiendo una variable para contener la información

Algo como

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

Eso no está del todo bien, pero entiendes la idea. Entonces System.getProperty("com.mycompany.workingDir")...

MJB
fuente
66
No relevante para la pregunta.
Peter De Winter
1
Tiene un significado para Java: es la ubicación en el disco donde están relacionados los archivos que abre con nombres de ruta relativos.
Rob I
2
Sí, tiene un significado. Mis palabras fueron un poco mal elegidas. Pero se le pasa el punto - antes de Java 7 no había manera de saber el directorio de trabajo actual, y las diferentes implementaciones de los configura de manera diferente ... ...
MJB
1

suponga que está intentando ejecutar su proyecto dentro de eclipse, o netbean o solo desde la línea de comandos. He escrito un método para arreglarlo

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, en cualquier lugar donde desee obtener la ruta base para leer el archivo, puede pasar su clase de ancla al método anterior, el resultado puede ser lo que necesita: D

Mejor,

bachden
fuente
2
Esto devuelve la ubicación del archivo JAR. No es lo que se pidió.
Marqués de Lorne
@ user207421 sí, sé que esta respuesta no es la respuesta verdadera para la pregunta, pero la mayoría de las veces, todos quieren obtener el "directorio donde se encuentran los frascos" en lugar del "directorio de trabajo de la línea de comandos".
bachden
0

Ninguna de las respuestas publicadas aquí funcionó para mí. Esto es lo que funcionó:

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

Editar: La versión final en mi 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()
Venerables Agentes
fuente
Esto devuelve la ubicación del archivo JAR. No es lo que se pidió.
Marqués de Lorne
0

Esta es mi bala de plata cuando aparece el momento de confusión. (Llámalo como lo primero en main). Quizás, por ejemplo, JVM se desliza para ser una versión diferente por IDE. Esta función estática busca el PID del proceso actual y abre VisualVM en ese pid. La confusión se detiene allí porque lo quieres todo y lo obtienes ...

  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();
    }
}
Kurskinen
fuente
-6

System.getProperty("java.class.path")

Marko Stojkovic
fuente
-7

este es el nombre del directorio actual

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

esta es la ruta actual del directorio

String path=folder.getPath();
Prasad De Silva
fuente
1
El OP quería el directorio de trabajo actual desde donde se ejecutó la aplicación.
Leif Gruenwoldt
Este es su directorio personal, no el directorio de trabajo actual de nadie, excepto quizás el suyo. No es lo que se pidió.
Marqués de Lorne