Bagaimana saya bisa mengubah direktori kerja saat ini dari dalam program Java? Segala sesuatu yang saya dapat temukan tentang masalah ini mengklaim bahwa Anda tidak dapat melakukannya, tetapi saya tidak dapat percaya bahwa itulah masalahnya.
Saya memiliki sepotong kode yang membuka file menggunakan jalur file relatif yang dikodekan keras dari direktori yang biasanya dimulai, dan saya hanya ingin dapat menggunakan kode itu dari dalam program Java yang berbeda tanpa harus memulainya dari dalam direktori tertentu. Sepertinya Anda seharusnya bisa menelepon System.setProperty( "user.dir", "/path/to/dir" )
, tetapi sejauh yang saya tahu, memanggil saluran itu hanya gagal dan tidak melakukan apa-apa.
Saya akan mengerti jika Java tidak memperbolehkan Anda untuk melakukan ini, jika bukan karena fakta bahwa itu memungkinkan Anda untuk mendapatkan direktori kerja saat ini, dan bahkan memungkinkan Anda untuk membuka file menggunakan jalur file relatif ....
sumber
Jawaban:
Tidak ada cara yang dapat diandalkan untuk melakukan ini di Jawa murni. Mengatur
user.dir
properti melaluiSystem.setProperty()
ataujava -Duser.dir=...
tampaknya mempengaruhi kreasi berikutnyaFiles
, tetapi tidak misalnyaFileOutputStreams
.The
File(String parent, String child)
konstruktor dapat membantu jika Anda membangun jalur direktori Anda terpisah dari path file Anda, memungkinkan swapping lebih mudah.Alternatifnya adalah dengan mengatur skrip untuk menjalankan Java dari direktori yang berbeda, atau menggunakan kode asli JNI seperti yang disarankan di bawah ini .
Bug Sun yang relevan ditutup pada 2008 karena "tidak akan diperbaiki".
sumber
new FileOutputStream("foo.txt").close();
membuat file di direktori kerja asli bahkan jika user.dir diubah oleh program.Jika Anda menjalankan program lawas Anda dengan ProcessBuilder , Anda akan dapat menentukan direktori kerjanya .
sumber
Ada adalah cara untuk melakukan hal ini menggunakan properti sistem "user.dir". Bagian penting untuk dipahami adalah getAbsoluteFile () harus dipanggil (seperti yang ditunjukkan di bawah ini) atau jalur relatif akan diselesaikan terhadap nilai "user.dir" default .
sumber
user.dir
. Fakta bahwa jalan absolut menjadi kritis membuktikannya.Dimungkinkan untuk mengubah PWD, menggunakan JNA / JNI untuk membuat panggilan ke libc. Orang-orang JRuby memiliki perpustakaan java yang berguna untuk membuat panggilan POSIX disebut jna-posix Inilah info pakar
Anda dapat melihat contoh penggunaannya di sini (kode Clojure, maaf). Lihatlah fungsi chdirToRoot
sumber
user.dir
properti sistem makaFile.getAbsolutePath()
akan memutuskan melawanuser.dir
, sedangkan pathname di File menyelesaikan terhadap direktori kerja OS.Seperti yang disebutkan Anda tidak dapat mengubah CWD dari JVM tetapi jika Anda meluncurkan proses lain menggunakan Runtime.exec () Anda dapat menggunakan metode kelebihan beban yang memungkinkan Anda menentukan direktori kerja. Ini bukan benar-benar untuk menjalankan program Java Anda di direktori lain tetapi untuk banyak kasus ketika seseorang perlu meluncurkan program lain seperti skrip Perl misalnya, Anda dapat menentukan direktori kerja skrip tersebut sambil membiarkan direktori kerja JVM tidak berubah.
Lihat Runtime.exec javadocs
Secara khusus,
di mana
dir
direktori kerja untuk menjalankan subproses disumber
Jika saya mengerti benar, program Java dimulai dengan salinan variabel lingkungan saat ini. Setiap perubahan via
System.setProperty(String, String)
memodifikasi salinan, bukan variabel lingkungan asli. Bukannya ini memberikan alasan menyeluruh mengapa Sun memilih perilaku ini, tapi mungkin itu sedikit memberi ...sumber
-D
. Tapi saya setuju, pada JVM mulai properti yang telah ditentukan sepertiuser.dir
disalin dari OS dan mengubahnya nanti tidak membantu.user.dir
mempengaruhiFile.getAbsolutePath()
danFile.getCanonicalPath()
, tetapi bukan gagasan OS tentang direktori kerja, yang menentukan bagaimana nama path file diselesaikan ketika mengakses file.Direktori kerja adalah fitur sistem operasi (ditetapkan saat proses dimulai). Mengapa Anda tidak melewati properti Sistem Anda sendiri (
-Dsomeprop=/my/path
) dan menggunakannya dalam kode Anda sebagai induk dari File Anda:sumber
Yang lebih pintar / lebih mudah untuk dilakukan di sini adalah hanya mengubah kode Anda sehingga alih-alih membuka file dengan asumsi bahwa itu ada di direktori kerja saat ini (saya berasumsi Anda sedang melakukan sesuatu seperti
new File("blah.txt")
, hanya membangun path ke file sendiri.Biarkan pengguna lewat di direktori basis, bacalah dari file konfigurasi, kembalilah ke
user.dir
jika properti lain tidak dapat ditemukan, dll. Tetapi jauh lebih mudah untuk meningkatkan logika dalam program Anda daripada mengubah cara variabel lingkungan bekerja.sumber
Saya sudah mencoba memohon
String oldDir = System.setProperty("user.dir", currdir.getAbsolutePath());
Sepertinya berhasil. Tapi
File myFile = new File("localpath.ext"); InputStream openit = new FileInputStream(myFile);
melempar
FileNotFoundException
meskipunmyFile.getAbsolutePath()
menunjukkan jalur yang benar. Saya sudah membaca ini . Saya pikir masalahnya adalah:
Solusinya mungkin:
File myFile = new File(System.getPropety("user.dir"), "localpath.ext");
Itu menciptakan objek file sebagai mutlak dengan direktori saat ini yang dikenal oleh JVM. Tetapi kode itu harus ada di kelas yang digunakan, perlu mengubah kode yang digunakan kembali.
~~~~ JcHartmut
sumber
Kamu bisa memakai
setelah
Akan dicetak
sumber
System.setProperty("user.dir", "/some/directory")
Jawaban lain yang mungkin untuk pertanyaan ini mungkin tergantung pada alasan Anda membuka file. Apakah ini file properti atau file yang memiliki beberapa konfigurasi yang terkait dengan aplikasi Anda?
Jika hal ini Anda mungkin mempertimbangkan untuk mencoba memuat file melalui loader classpath, dengan cara ini Anda dapat memuat file apa pun yang memiliki akses Java.
sumber
Jika Anda menjalankan perintah dalam sebuah shell, Anda dapat menulis sesuatu seperti "java -cp" dan menambahkan direktori yang ingin Anda pisahkan dengan ":" jika java tidak menemukan sesuatu dalam satu direktori, ia akan mencoba dan menemukannya di direktori lain, yang adalah apa yang saya lakukan.
sumber
Anda dapat mengubah direktori kerja proses yang sebenarnya menggunakan JNI atau JNA.
Dengan JNI, Anda dapat menggunakan fungsi asli untuk mengatur direktori. Metode POSIX adalah
chdir()
. Di Windows, Anda bisa menggunakanSetCurrentDirectory()
.Dengan JNA, Anda dapat membungkus fungsi-fungsi asli dalam Java binder.
Untuk Windows:
Untuk sistem POSIX:
sumber
Gunakan FileSystemView
sumber