Como posso alterar o diretório de trabalho atual de um programa Java? Tudo o que pude encontrar sobre o problema afirma que você simplesmente não pode fazê-lo, mas não acredito que esse seja realmente o caso.
Eu tenho um pedaço de código que abre um arquivo usando um caminho de arquivo relativo codificado no diretório em que ele normalmente é iniciado e eu só quero poder usar esse código em um programa Java diferente sem precisar iniciá-lo de dentro um diretório específico. Parece que você deveria ser capaz de ligar System.setProperty( "user.dir", "/path/to/dir" )
, mas até onde eu sei, ligar para essa linha falha silenciosamente e não faz nada.
Eu entenderia se o Java não permitiu que você fizesse isso, se não fosse pelo fato de permitir que você obtenha o diretório de trabalho atual e até mesmo que você abra arquivos usando caminhos de arquivo relativos ...
fonte
Respostas:
Não há maneira confiável de fazer isso em Java puro. Definir a
user.dir
propriedade viaSystem.setProperty()
oujava -Duser.dir=...
parece afetar criações subsequentes deFiles
, mas não por exemploFileOutputStreams
.O
File(String parent, String child)
construtor pode ajudar se você criar o caminho do diretório separadamente do caminho do arquivo, permitindo uma troca mais fácil.Uma alternativa é configurar um script para executar o Java a partir de um diretório diferente ou usar o código nativo JNI, conforme sugerido abaixo .
O bug relevante da Sun foi encerrado em 2008 como "não será corrigido".
fonte
new FileOutputStream("foo.txt").close();
cria o arquivo no diretório de trabalho original, mesmo que o user.dir seja alterado pelo programa.Se você executar seu programa legado com o ProcessBuilder , poderá especificar seu diretório de trabalho .
fonte
Não é uma maneira de fazer isso usando a propriedade do sistema "user.dir". A parte principal a entender é que getAbsoluteFile () deve ser chamado (como mostrado abaixo) ou os caminhos relativos serão resolvidos com o valor padrão "user.dir".
fonte
user.dir
. O fato de o caminho absoluto se tornar crítico prova isso.É possível alterar o PWD, usando JNA / JNI para fazer chamadas para libc. Os caras do JRuby têm uma biblioteca java útil para fazer chamadas POSIX chamadas jna-posix. Aqui estão as informações importantes
Você pode ver um exemplo de seu uso aqui (código Clojure, desculpe). Veja a função chdirToRoot
fonte
user.dir
propriedade do sistema,File.getAbsolutePath()
será resolvidouser.dir
, enquanto o nome do caminho em Arquivo será resolvido no diretório de trabalho do SO.Como mencionado, você não pode alterar o CWD da JVM, mas se você iniciar outro processo usando Runtime.exec (), poderá usar o método sobrecarregado que permite especificar o diretório de trabalho. Isso não é realmente para executar seu programa Java em outro diretório, mas em muitos casos quando é necessário iniciar outro programa como um script Perl, por exemplo, você pode especificar o diretório de trabalho desse script enquanto mantém inalterado o diretório de trabalho da JVM.
Veja Runtime.exec javadocs
Especificamente,
onde
dir
é o diretório de trabalho para executar o subprocesso nofonte
Se bem entendi, um programa Java começa com uma cópia das variáveis de ambiente atuais. Quaisquer alterações via
System.setProperty(String, String)
estão modificando a cópia, não as variáveis de ambiente originais. Não que isso forneça uma razão completa da razão pela qual a Sun escolheu esse comportamento, mas talvez ele mostre um pouco de luz ...fonte
-D
. Mas eu concordo que, na JVM, inicie propriedades predefinidas, comouser.dir
copiadas do sistema operacional e alterá-las posteriormente, não ajuda.user.dir
afetaFile.getAbsolutePath()
eFile.getCanonicalPath()
, mas não a idéia do diretório de trabalho do sistema operacional, que determina como os nomes de caminho de arquivos são resolvidos ao acessar arquivos.O diretório de trabalho é um recurso do sistema operacional (definido quando o processo é iniciado). Por que você simplesmente não passa sua própria propriedade System (
-Dsomeprop=/my/path
) e a usa no seu código como pai do seu arquivo:fonte
A coisa mais inteligente / fácil de fazer aqui é alterar seu código para que, em vez de abrir o arquivo, suponha que ele exista no diretório de trabalho atual (suponho que você esteja fazendo algo parecido
new File("blah.txt")
, apenas construa o caminho para o arquivo).Permita que o usuário passe no diretório base, leia-o em um arquivo de configuração, volte para
user.dir
outras propriedades não encontradas, etc. Mas é muito mais fácil melhorar a lógica do seu programa do que mudar a forma como variáveis de ambiente funcionam.fonte
Eu tentei invocar
String oldDir = System.setProperty("user.dir", currdir.getAbsolutePath());
Parece funcionar. Mas
File myFile = new File("localpath.ext"); InputStream openit = new FileInputStream(myFile);
joga um
FileNotFoundException
pensamentomyFile.getAbsolutePath()
mostra o caminho correto. Eu li isso . Eu acho que o problema é:
A solução pode ser:
File myFile = new File(System.getPropety("user.dir"), "localpath.ext");
Ele cria um objeto de arquivo como absoluto com o diretório atual que é conhecido pela JVM. Mas esse código deve existir em uma classe usada, ele precisa ser alterado de códigos reutilizados.
~~~~ JcHartmut
fonte
Você pode usar
depois de
Vai imprimir
fonte
System.setProperty("user.dir", "/some/directory")
A outra resposta possível a esta pergunta pode depender do motivo pelo qual você está abrindo o arquivo. Este é um arquivo de propriedades ou um arquivo que possui alguma configuração relacionada ao seu aplicativo?
Se for esse o caso, considere tentar carregar o arquivo através do carregador de caminho de classe, dessa forma, você poderá carregar qualquer arquivo ao qual Java tenha acesso.
fonte
Se você executar seus comandos em um shell, poderá escrever algo como "java -cp" e adicionar os diretórios que desejar, separados por ":" se o java não encontrar algo em um diretório, ele tentará encontrá-los nos outros diretórios. é o que eu faço.
fonte
Você pode alterar o diretório de trabalho real do processo usando JNI ou JNA.
Com o JNI, você pode usar funções nativas para definir o diretório. O método POSIX é
chdir()
. No Windows, você pode usarSetCurrentDirectory()
.Com o JNA, você pode agrupar as funções nativas nos ligadores Java.
Para Windows:
Para sistemas POSIX:
fonte
Use o FileSystemView
fonte