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

112

Digamos que tengo mi clase principal en C:\Users\Justian\Documents\. ¿Cómo puedo hacer que mi programa muestre que está incluido C:\Users\Justian\Documents?

La codificación rígida no es una opción; debe ser adaptable si se traslada a otra ubicación.

Quiero volcar un montón de archivos CSV en una carpeta, hacer que el programa reconozca todos los archivos, luego cargar los datos y manipularlos. Realmente solo quiero saber cómo navegar hasta esa carpeta.

Justian Meyer
fuente
1
Echa un vistazo a este artículo .
Matthew J Morrison
1
¿Qué pasa si su clase principal está en un archivo jar? ¿Qué tipo de resultado querría entonces?
Mattias Nilsson
1
¿Por qué necesitarías hacer esto de todos modos?
Ed S.
1
Parece que lo que necesita es el directorio en el que se encuentran los archivos CSV y que el archivo .jar pueda hacer referencia a ese directorio, vea mi respuesta si ese es el caso.

Respuestas:

149

Una forma sería usar la propiedad del sistema,System.getProperty("user.dir"); esto le dará "El directorio de trabajo actual cuando se inicializaron las propiedades". Probablemente esto es lo que quieres. para averiguar dónde javase emitió el comando, en su caso en el directorio con los archivos a procesar, aunque el archivo .jar real puede residir en otro lugar de la máquina. Tener el directorio del archivo .jar real no es tan útil en la mayoría de los casos.

A continuación, se imprimirá el directorio actual desde donde se invocó el comando, independientemente de dónde se encuentre el archivo .class o .jar.

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

si está dentro /User/me/y su archivo .jar que contiene el código anterior está en /opt/some/nested/dir/ el comando java -jar /opt/some/nested/dir/test.jar Testsaldrácurrent dir = /User/me .

También debería considerar como un bono el uso de un buen analizador de argumentos de línea de comando orientado a objetos. Recomiendo encarecidamente JSAP , el analizador de argumentos simple de Java. Esto le permitiría usar System.getProperty("user.dir")y, alternativamente, pasar algo más para anular el comportamiento. Una solución mucho más fácil de mantener. Esto haría que pasar en el directorio para procesar sea muy fácil de hacer y podría recurrir user.dirsi no se pasa nada.


fuente
Probaré esto cuando pueda. Estoy realmente preocupado con ese problema .jar: P
Justian Meyer
¿Visitó el enlace en mi respuesta a ese problema .jar, donde muestro cómo construir el archivo .jar con ANT?
El código de Jarrod que devuelve la ruta absoluta del directorio de trabajo actual de la propiedad del sistema user.dires mucho más fácil de usar. System.getProperty ("user.dir");
74

Utilice 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());
    }
}

Actualización según el comentario del OP:

Quiero volcar un montón de archivos CSV en una carpeta, hacer que el programa reconozca todos los archivos, luego cargar los datos y manipularlos. Realmente solo quiero saber cómo navegar hasta esa carpeta.

Eso requeriría codificar / conocer su ruta relativa en su programa. Más bien, considere agregar su ruta a la ruta de clases para que pueda 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");
    }
});

O pasar su camino como main()argumento.

BalusC
fuente
3
+1. Hay varias condiciones para que esto funcione; lo más importante es que su "clase principal" se cargue desde el sistema de archivos. En Java, no es muy inusual que esta suposición sea falsa. Pero, si está seguro de que está cargando su clase desde un JAR en el sistema de archivos, este es el método que funciona.
erickson
Todo depende, de verdad. Estoy tratando de compilar mi JAR, pero ese es un problema separado en este momento. Si cree que puede ayudar con eso, consulte: stackoverflow.com/questions/3152240/… . Estoy seguro de que publicar esto es una infracción de algún tipo, pero está relacionado con este problema. Si puedo arreglar eso, seguramente esta será mi respuesta.
Justian Meyer
¿Por qué tendría que codificar eso? He hecho cosas similares antes. Supongamos que mi jar y mi carpeta siempre tendrán una relación similar (es decir, en el mismo directorio). Si esto fuera cierto, podría obtener el directorio del jar y luego modificarlo para encontrar la carpeta.
Justian Meyer
Si está en la misma carpeta que el archivo JAR, entonces ya está en la ruta de clases. La palabra "codificación" es un poco exagerada, en realidad me refería a "conocer su ruta relativa al archivo JAR".
BalusC
1
@Moebius: ¿Eh? ¿Eres nuevo en Java? Compruebe el javadoc . Solo use exactamente ese como lo devolviógetLocation() método. Otros, obviamente, no van a funcionar.
BalusC
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/.

Tenga en cuenta que File.getCanonicalPath()arroja una IOException marcada pero eliminará cosas como ../../../

ciber-monje
fuente
13
this.getClass().getClassLoader().getResource("").getPath()
Peter De Winter
fuente
tenga en cuenta que esto devolverá la ruta al "bin / classes /", y no solo al "bin".
desarrollador de Android
mientras se depuraba una aplicación en ejecución con Intellij Idea, esto devolvía "/C:/Program%20Files/Java/jdk1.8.0_112/:"
velocidad
5

Acabo de usar:

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

...

Path workingDirectory=Paths.get(".").toAbsolutePath();
usuario3696181
fuente
9
El suyo no está funcionando, este es el correctoPaths.get("").toAbsolutePath();
A Kra
@ToKra Si lo hago, Paths.get("my/file").toAbsolutePath()lo consigo /my/file, que definitivamente no es el cwd.
abergmeier
1
@abergmeier Escribí "" en la cadena, no en "mi / archivo"
Para Kra
5

Si desea obtener su directorio de trabajo actual, use la siguiente línea

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

Si desea la ruta absoluta del código fuente actual, mi sugerencia es:

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
fuente
Esto no funciona cuando lo ejecuta en un IDE o usa algo para hacer girar la instancia.
Sarp Kaya
La ruta interna es java \ lang \ Class La ruta externa es E: \ BranchProduction1.4.0 \ FilesTestProject \ src El directorio de trabajo es E: \ BranchProduction1.4.0 \ FilesTestProject \ src \ java \ lang ¿podría explicar el resultado?
JAVA
3

¿Quién dice que su clase principal está en un archivo en un disco duro local? Las clases se incluyen con mayor frecuencia dentro de archivos JAR y, a veces, se cargan a través de la red o incluso se generan sobre la marcha.

Entonces, ¿qué es lo que realmente quieres hacer? Probablemente haya una forma de hacerlo que no haga suposiciones sobre el origen de las clases.

Michael Borgwardt
fuente
Quiero volcar un montón de archivos CSV en una carpeta, hacer que el programa reconozca todos los archivos, luego cargar los datos y manipularlos. Realmente solo quiero saber cómo navegar hasta esa carpeta.
Justian Meyer
Quizás me estoy perdiendo algo, pero parece que una ruta absoluta funcionaría. Dijiste que no puedes codificarlo, pero ¿cómo vas a saber en qué carpeta buscar para empezar?
Chris Thompson
Bueno, el problema es que quiero llevarlo a otras computadoras, no solo a la mía. No veo cómo funcionaría la codificación de la ruta. "Supongamos que mi jar y mi carpeta siempre tendrán una relación similar (es decir, en el mismo directorio). Si esto fuera cierto, podría obtener el directorio del jar y luego modificarlo para encontrar la carpeta". La única forma en que podría codificarlo sería si no tuviera que incluir la ruta completa desde el disco duro al archivo. Tal vez pueda retroceder solo 3 carpetas (es decir, "Documentos \ Proyecto \ Dump \ [archivo / carpeta]")
Justian Meyer
Yo diría que lo que quiere hacer es obtener un identificador del directorio en el que reside el archivo jar. ¿Cumpliría con sus requisitos?
Chris Thompson