getpath - java pwd directory
¿Cambiar el directorio de trabajo actual en Java? (13)
¿Cómo puedo cambiar el directorio actual de trabajo desde dentro de un programa Java? Todo lo que he podido encontrar sobre el tema afirma que simplemente no puede hacerlo, pero no puedo creer que ese sea realmente el caso.
Tengo un fragmento de código que abre un archivo usando una ruta de archivo relativamente codificada desde el directorio en el que normalmente se inició, y solo quiero poder usar ese código desde un programa Java diferente sin tener que iniciarlo desde dentro un directorio particular. Parece que solo deberías poder llamar a System.setProperty( "user.dir", "/path/to/dir" )
, pero hasta donde sé, llamar a esa línea simplemente falla silenciosamente y no hace nada.
Entiendo si Java no te permitió hacer esto, si no fuera por el hecho de que te permite obtener el directorio de trabajo actual, e incluso te permite abrir archivos usando rutas de archivos relativas ...
Como se mencionó, no se puede cambiar la CWD de la JVM, pero si se iniciara otro proceso con Runtime.exec (), se puede usar el método sobrecargado que le permite especificar el directorio de trabajo. Esto no es realmente para ejecutar su programa Java en otro directorio, pero en muchos casos cuando se necesita iniciar otro programa como un script Perl, por ejemplo, puede especificar el directorio de trabajo de ese script sin modificar el directorio de trabajo de la JVM.
Ver Runtime.exec javadocs
Específicamente,
public Process exec(String[] cmdarray,String[] envp, File dir) throws IOException
donde dir
es el directorio de trabajo para ejecutar el subproceso en
El directorio de trabajo es una función del sistema operativo (se establece cuando se inicia el proceso). ¿Por qué no pasa su propiedad del sistema ( -Dsomeprop=/my/path
) y la usa en su código como padre de su archivo?
File f = new File ( System.getProperty("someprop"), myFilename)
Es posible cambiar la PWD, usando JNA / JNI para hacer llamadas a libc. Los chicos de JRuby tienen una útil biblioteca de java para hacer llamadas POSIX llamada jna-posix Aquí está la información de Maven.
Puede ver un ejemplo de su uso here (código Clojure, lo siento). Mira la función chdirToRoot
Hay una forma de hacerlo utilizando la propiedad del sistema "user.dir". La parte clave para comprender es que se debe llamar a getAbsoluteFile () (como se muestra a continuación) o de lo contrario las rutas relativas se resolverán con el valor "user.dir" predeterminado .
import java.io.*;
public class FileUtils
{
public static boolean setCurrentDirectory(String directory_name)
{
boolean result = false; // Boolean indicating whether directory was set
File directory; // Desired current working directory
directory = new File(directory_name).getAbsoluteFile();
if (directory.exists() || directory.mkdirs())
{
result = (System.setProperty("user.dir", directory.getAbsolutePath()) != null);
}
return result;
}
public static PrintWriter openOutputFile(String file_name)
{
PrintWriter output = null; // File to open for writing
try
{
output = new PrintWriter(new File(file_name).getAbsoluteFile());
}
catch (Exception exception) {}
return output;
}
public static void main(String[] args) throws Exception
{
FileUtils.openOutputFile("DefaultDirectoryFile.txt");
FileUtils.setCurrentDirectory("NewCurrentDirectory");
FileUtils.openOutputFile("CurrentDirectoryFile.txt");
}
}
He intentado invocar
String oldDir = System.setProperty("user.dir", currdir.getAbsolutePath());
Parece funcionar. Pero
File myFile = new File("localpath.ext"); InputStream openit = new FileInputStream(myFile);
arroja una FileNotFoundException
myFile.getAbsolutePath()
muestra el camino correcto. He leído esto Creo que el problema es:
- Java conoce el directorio actual con la nueva configuración.
- Pero el manejo de archivos lo realiza el sistema operativo. Desconoce el nuevo directorio actual del conjunto, desafortunadamente.
La solución puede ser:
File myFile = new File(System.getPropety("user.dir"), "localpath.ext");
Crea un objeto de archivo como absoluto con el directorio actual que conoce la JVM. Pero ese código debería existir en una clase usada, necesita cambiar los códigos reutilizados.
~~~~ JcHartmut
La otra respuesta posible a esta pregunta puede depender del motivo por el que abre el archivo. ¿Es este un archivo de propiedad o un archivo que tiene alguna configuración relacionada con su aplicación?
Si este es el caso, puede considerar intentar cargar el archivo a través del cargador de rutas de clase, de esta forma puede cargar cualquier archivo al que Java tenga acceso.
Lo más inteligente / más fácil de hacer aquí es simplemente cambiar tu código para que en lugar de abrir el archivo suponiendo que exista en el directorio de trabajo actual (supongo que estás haciendo algo como el new File("blah.txt")
, simplemente crea la ruta al archivo usted mismo.
Permita que el usuario pase en el directorio base, user.dir
desde un archivo de configuración, vuelva a user.dir
si no se encuentran las otras propiedades, etc. Pero es mucho más fácil mejorar la lógica en su programa de lo que es para cambiar cómo funcionan las variables de entorno
No hay una manera confiable de hacer esto en Java puro. Establecer la propiedad user.dir
través de System.setProperty()
o java -Duser.dir=...
parece afectar las creaciones posteriores de Files
, pero no, por ejemplo, FileOutputStreams
.
El constructor File(String parent, String child)
puede ayudar si construye su ruta de directorio por separado de su ruta de archivo, lo que permite un intercambio más fácil.
Una alternativa es configurar un script para ejecutar Java desde un directorio diferente, o usar el código nativo JNI como se sugiere a continuación .
El error de Sun correspondiente se cerró en 2008 como "no se solucionará".
Puedes usar
nuevo archivo ("relativo / ruta"). getAbsoluteFile ()
después
System.setProperty ("user.dir", "/ some / directory")
System.setProperty("user.dir", "C:/OtherProject");
File file = new File("data/data.csv").getAbsoluteFile();
System.out.println(file.getPath());
Se imprimirá
C:/OtherProject/data/data.csv
Si ejecuta los comandos en un shell, puede escribir algo como "java -cp" y agregar los directorios que quiera separados por ":" si java no encuentra algo en un directorio, intentará encontrarlos en los otros directorios, eso es lo que hago
Si ejecuta su programa heredado con ProcessBuilder , podrá especificar su directory trabajo.
Si entiendo correctamente, un programa Java comienza con una copia de las variables de entorno actuales. Cualquier cambio a través de System.setProperty(String, String)
está modificando la copia, no las variables de entorno originales. No es que esto proporcione una razón exhaustiva de por qué Sun eligió este comportamiento, pero tal vez arroja un poco de luz ...
Use FileSystemView
private FileSystemView fileSystemView;
fileSystemView = FileSystemView.getFileSystemView();
currentDirectory = new File(".");
//listing currentDirectory
File[] filesAndDirs = fileSystemView.getFiles(currentDirectory, false);
fileList = new ArrayList<File>();
dirList = new ArrayList<File>();
for (File file : filesAndDirs) {
if (file.isDirectory())
dirList.add(file);
else
fileList.add(file);
}
Collections.sort(dirList);
if (!fileSystemView.isFileSystemRoot(currentDirectory))
dirList.add(0, new File(".."));
Collections.sort(fileList);
//change
currentDirectory = fileSystemView.getParentDirectory(currentDirectory);