Jangan lupa Path.toAbsolutePath().normalize()yang merupakan jalan tengah yang baik antara jalur kanonik (nyata) dan jalur absolut saja.
eckes
Jawaban:
625
Pertimbangkan nama file ini:
C:\temp\file.txt - Ini adalah jalan, jalan absolut, dan jalan kanonik.
.\file.txt- Ini jalan. Itu bukan jalan absolut atau jalan kanonik.
C:\temp\myapp\bin\..\\..\file.txt- Ini adalah jalur dan jalur absolut. Itu bukan jalan kanonik.
Jalan kanonik selalu merupakan jalan absolut.
Mengubah dari jalur ke jalur kanonik menjadikannya absolut (biasanya menempel pada direktori kerja saat ini, jadi misalnya ./file.txtmenjadi c:/temp/file.txt). Path kanonik file hanya "memurnikan" path, menghapus dan menyelesaikan hal-hal seperti ..\dan menyelesaikan symlink (pada unix).
FWIW, ini bukan C:\temp\file.txtmerupakan jalur kanonik - direktori temp mungkin berupa tautan lunak sistem file atau tautan keras (persimpangan di NTFS), dan file.txt mungkin merupakan tautan lunak. Saya tidak tahu apakah sistem file dapat membedakan tautan keras ke file.
Lawrence Dol
1
path tidak benar-benar mempertimbangkan masalah-masalah atau keberadaan salah satu komponen, hanya sintaksisnya.
escape-llc
Ya, jalur kanonik (tidak seperti jalur dinormalisasi) tidak mengenai sistem file.
eckes
1
Pada dasarnya, saya tidak bisa melihat alasan mengapa orang harus menggunakan getAbsolutePath()bukan getCanonicalPath(). Bahkan terlihat lebih baik karena kanonik secara otomatis menyelesaikan ../bagian - bagian itu.
Scadge
Jangan lupa bahwa getCanonicalPathmelempar IOExceptionsebentar getAbsolutePathtidak, jika ini pertimbangan.
Abandoned Cart
129
Cara terbaik yang saya temukan untuk merasakan hal-hal seperti ini adalah dengan mencobanya:
import java.io.File;publicclassPathTesting{publicstaticvoid main(String[] args){File f =newFile("test/.././file.txt");System.out.println(f.getPath());System.out.println(f.getAbsolutePath());try{System.out.println(f.getCanonicalPath());}catch(Exception e){}}}
Jadi, getPath()memberi Anda jalan berdasarkan objek File, yang mungkin atau mungkin tidak relatif; getAbsolutePath()memberi Anda jalur absolut ke file; dan getCanonicalPath()memberi Anda jalur absolut unik ke file. Perhatikan bahwa ada sejumlah besar jalur absolut yang menunjuk ke file yang sama, tetapi hanya satu jalur kanonik.
Kapan harus menggunakan masing-masing? Tergantung pada apa yang ingin Anda capai, tetapi jika Anda mencoba melihat apakah keduanya Filesmenunjuk pada file yang sama pada disk, Anda dapat membandingkan jalur kanonik mereka. Hanya satu contoh.
Dapat diperdebatkan bahwa Java salah menerapkan implementasi jalur "absolut"; itu benar-benar harus menghapus elemen jalur relatif di jalur absolut. Bentuk kanonik kemudian akan menghapus tautan atau persimpangan FS apa pun di jalur.
Lawrence Dol
but if you were trying to see if two Files are pointing at the same file on diskBagaimana? contoh tolong?
Asif Mushtaq
@UnKnown: Anda akan menggunakan jalur kanonik untuk itu.
Lawrence Dol
67
Pendeknya:
getPath()mendapat string jalur yang Fileobjeknya dibangun, dan itu mungkin direktori relatif saat ini.
getAbsolutePath() mendapatkan string path setelah menyelesaikannya terhadap direktori saat ini jika itu relatif, menghasilkan path yang sepenuhnya memenuhi syarat.
getCanonicalPath()mendapatkan string path setelah menyelesaikan path relatif terhadap direktori saat ini, dan menghapus path relatif ( .dan ..), dan semua sistem file link untuk mengembalikan path yang sistem file menganggap sarana kanonik untuk merujuk objek sistem file yang ditunjuknya.
Juga, masing-masing memiliki File yang setara yang mengembalikan Fileobjek yang sesuai .
getPath()mengembalikan jalur yang digunakan untuk membuat Fileobjek. Nilai pengembalian ini tidak berubah berdasarkan lokasi dijalankan (hasil di bawah ini adalah untuk windows, pemisah jelas berbeda di tempat lain)
File f1 =newFile("/some/path");String path = f1.getPath();// will return "\some\path"File dir =newFile("/basedir");File f2 =newFile(dir,"/some/path");
path = f2.getPath();// will return "\basedir\some\path"File f3 =newFile("./some/path");
path = f3.getPath();// will return ".\some\path"
getAbsolutePath()akan menyelesaikan jalur berdasarkan lokasi eksekusi atau drive. Jadi jika lari dari c:\test:
path = f1.getAbsolutePath();// will return "c:\some\path"
path = f2.getAbsolutePath();// will return "c:\basedir\some\path"
path = f3.getAbsolutePath();// will return "c:\test\.\basedir\some\path"
getCanonicalPath()tergantung sistem. Ini akan menyelesaikan lokasi unik yang dilambangkan oleh jalur. Jadi, jika Anda memiliki "." Di jalan mereka biasanya akan dihapus.
Seperti kapan menggunakannya. Itu tergantung pada apa yang ingin Anda capai. getPath()berguna untuk portabilitas. getAbsolutePath()berguna untuk menemukan lokasi sistem file, dan getCanonicalPath()sangat berguna untuk memeriksa apakah dua file itu sama.
dapatkah Anda memberi saya contoh tentang ini? getCanonicalPath() is particularly useful to check if two files are the same.
Asif Mushtaq
20
Hal besar yang perlu Anda perhatikan adalah bahwa Filekelas mencoba untuk mewakili pandangan dari apa yang disebut Sun sebagai "nama path hierarkis" (pada dasarnya path seperti c:/foo.txtatau /usr/muggins). Inilah sebabnya mengapa Anda membuat file dalam hal jalur. Operasi yang Anda gambarkan adalah semua operasi pada "pathname" ini.
getPath()mengambil jalur tempat File dibuat dengan ( ../foo.txt)
getAbsolutePath()mengambil jalur tempat File dibuat, tetapi menyertakan informasi tentang direktori saat ini jika jalur relatif ( /usr/bobstuff/../foo.txt)
getCanonicalPath()mencoba mengambil representasi unik dari jalur absolut ke file. Ini menghilangkan tipuan dari ".." dan "." referensi ( /usr/foo.txt).
Catatan saya katakan upaya - dalam membentuk Canonical Path, VM dapat melempar IOException. Ini biasanya terjadi karena ia menjalankan beberapa operasi sistem file, yang salah satunya bisa gagal.
Saya menemukan saya jarang perlu menggunakan getCanonicalPath()tetapi, jika diberi File dengan nama file yang ada dalam format DOS 8.3 di Windows, seperti java.io.tmpdirpengembalian properti Sistem, maka metode ini akan mengembalikan nama file "lengkap".
Path.toAbsolutePath().normalize()
yang merupakan jalan tengah yang baik antara jalur kanonik (nyata) dan jalur absolut saja.Jawaban:
Pertimbangkan nama file ini:
C:\temp\file.txt
- Ini adalah jalan, jalan absolut, dan jalan kanonik..\file.txt
- Ini jalan. Itu bukan jalan absolut atau jalan kanonik.C:\temp\myapp\bin\..\\..\file.txt
- Ini adalah jalur dan jalur absolut. Itu bukan jalan kanonik.Jalan kanonik selalu merupakan jalan absolut.
Mengubah dari jalur ke jalur kanonik menjadikannya absolut (biasanya menempel pada direktori kerja saat ini, jadi misalnya
./file.txt
menjadic:/temp/file.txt
). Path kanonik file hanya "memurnikan" path, menghapus dan menyelesaikan hal-hal seperti..\
dan menyelesaikan symlink (pada unix).Perhatikan juga contoh berikut dengan nio.Paths:
Sementara kedua jalur merujuk ke lokasi yang sama, hasilnya akan sangat berbeda:
sumber
C:\temp\file.txt
merupakan jalur kanonik - direktori temp mungkin berupa tautan lunak sistem file atau tautan keras (persimpangan di NTFS), dan file.txt mungkin merupakan tautan lunak. Saya tidak tahu apakah sistem file dapat membedakan tautan keras ke file.getAbsolutePath()
bukangetCanonicalPath()
. Bahkan terlihat lebih baik karena kanonik secara otomatis menyelesaikan../
bagian - bagian itu.getCanonicalPath
melemparIOException
sebentargetAbsolutePath
tidak, jika ini pertimbangan.Cara terbaik yang saya temukan untuk merasakan hal-hal seperti ini adalah dengan mencobanya:
Output Anda akan seperti:
Jadi,
getPath()
memberi Anda jalan berdasarkan objek File, yang mungkin atau mungkin tidak relatif;getAbsolutePath()
memberi Anda jalur absolut ke file; dangetCanonicalPath()
memberi Anda jalur absolut unik ke file. Perhatikan bahwa ada sejumlah besar jalur absolut yang menunjuk ke file yang sama, tetapi hanya satu jalur kanonik.Kapan harus menggunakan masing-masing? Tergantung pada apa yang ingin Anda capai, tetapi jika Anda mencoba melihat apakah keduanya
Files
menunjuk pada file yang sama pada disk, Anda dapat membandingkan jalur kanonik mereka. Hanya satu contoh.sumber
but if you were trying to see if two Files are pointing at the same file on disk
Bagaimana? contoh tolong?Pendeknya:
getPath()
mendapat string jalur yangFile
objeknya dibangun, dan itu mungkin direktori relatif saat ini.getAbsolutePath()
mendapatkan string path setelah menyelesaikannya terhadap direktori saat ini jika itu relatif, menghasilkan path yang sepenuhnya memenuhi syarat.getCanonicalPath()
mendapatkan string path setelah menyelesaikan path relatif terhadap direktori saat ini, dan menghapus path relatif (.
dan..
), dan semua sistem file link untuk mengembalikan path yang sistem file menganggap sarana kanonik untuk merujuk objek sistem file yang ditunjuknya.Juga, masing-masing memiliki File yang setara yang mengembalikan
File
objek yang sesuai .sumber
getPath()
mengembalikan jalur yang digunakan untuk membuatFile
objek. Nilai pengembalian ini tidak berubah berdasarkan lokasi dijalankan (hasil di bawah ini adalah untuk windows, pemisah jelas berbeda di tempat lain)getAbsolutePath()
akan menyelesaikan jalur berdasarkan lokasi eksekusi atau drive. Jadi jika lari daric:\test
:getCanonicalPath()
tergantung sistem. Ini akan menyelesaikan lokasi unik yang dilambangkan oleh jalur. Jadi, jika Anda memiliki "." Di jalan mereka biasanya akan dihapus.Seperti kapan menggunakannya. Itu tergantung pada apa yang ingin Anda capai.
getPath()
berguna untuk portabilitas.getAbsolutePath()
berguna untuk menemukan lokasi sistem file, dangetCanonicalPath()
sangat berguna untuk memeriksa apakah dua file itu sama.sumber
getCanonicalPath() is particularly useful to check if two files are the same.
Hal besar yang perlu Anda perhatikan adalah bahwa
File
kelas mencoba untuk mewakili pandangan dari apa yang disebut Sun sebagai "nama path hierarkis" (pada dasarnya path sepertic:/foo.txt
atau/usr/muggins
). Inilah sebabnya mengapa Anda membuat file dalam hal jalur. Operasi yang Anda gambarkan adalah semua operasi pada "pathname" ini.getPath()
mengambil jalur tempat File dibuat dengan (../foo.txt
)getAbsolutePath()
mengambil jalur tempat File dibuat, tetapi menyertakan informasi tentang direktori saat ini jika jalur relatif (/usr/bobstuff/../foo.txt
)getCanonicalPath()
mencoba mengambil representasi unik dari jalur absolut ke file. Ini menghilangkan tipuan dari ".." dan "." referensi (/usr/foo.txt
).Catatan saya katakan upaya - dalam membentuk Canonical Path, VM dapat melempar
IOException
. Ini biasanya terjadi karena ia menjalankan beberapa operasi sistem file, yang salah satunya bisa gagal.sumber
Saya menemukan saya jarang perlu menggunakan
getCanonicalPath()
tetapi, jika diberi File dengan nama file yang ada dalam format DOS 8.3 di Windows, sepertijava.io.tmpdir
pengembalian properti Sistem, maka metode ini akan mengembalikan nama file "lengkap".sumber