Perbedaan antara File.separator dan garis miring di


200

Apa perbedaan antara menggunakan File.separatordan normal /dalam Java Path-String?

Berbeda dengan \\independensi platform backslash ganda tampaknya bukan menjadi alasan, karena kedua versi bekerja di bawah Windows dan Unix.

public class SlashTest {
    @Test
    public void slash() throws Exception {
        File file = new File("src/trials/SlashTest.java");
        assertThat(file.exists(), is(true));
    }

    @Test
    public void separator() throws Exception {
        File file = new File("src" + File.separator + "trials" + File.separator + "SlashTest.java");
        assertThat(file.exists(), is(true));
    }
}

Untuk mengulangi pertanyaannya, jika /bekerja pada Unix dan Windows, mengapa orang ingin menggunakannya File.separator?


5
@ Membawa 'Alasan historis' seperti apa?
Marquis of Lorne

Jawaban:


246

Dengan perpustakaan Java untuk menangani file, Anda dapat menggunakan /(slash, bukan backslash) dengan aman di semua platform. Kode pustaka menangani penerjemahan berbagai hal ke jalur khusus platform secara internal.

Anda mungkin ingin menggunakan File.separatordi UI, karena itu terbaik untuk menunjukkan kepada orang-orang apa yang akan masuk akal di OS mereka, daripada apa yang masuk akal untuk Java.

Pembaruan : Saya belum dapat, dalam lima menit pencarian, untuk menemukan perilaku "Anda selalu dapat menggunakan tebasan" yang didokumentasikan. Sekarang, saya yakin saya telah melihatnya didokumentasikan, tetapi tanpa adanya referensi resmi (karena ingatan saya tidak sempurna), saya tetap menggunakan File.separatorkarena Anda tahu itu akan berhasil.


2
Ini juga mungkin masalah dengan kinerja, karena Anda mengharapkan pemisah akan dikonversi menjadi sesuatu yang lain saat runtime. Juga, jangan berharap ini terjadi di semua JVM yang tidak didukung di luar sana.
jpabluz

7
@TJ Crowder: "Saya belum bisa, dalam lima menit pencarian, untuk menemukan perilaku 'Anda selalu dapat menggunakan garis miring' yang didokumentasikan." Ini bukan fitur JVM, ini fitur Windows NT API.
Powerlord

12
@ Powerlord: Jika Windows juga melakukannya, bagus - tetapi perpustakaan (bukan JVM) juga melakukannya. Secara khusus, Filemenggunakan FileSystem.normalizesemua tempat untuk "menormalkan" jalur yang diterima melalui API publik, dan hampir semua hal yang berhubungan dengan string jalur file (misalnya, FileWriter(String)) digunakan di Filebawah selimut.
TJ Crowder

9
Karena Java7 tidak perlu menggunakan File.separator lagi. Jauh lebih sederhana dan bersih untuk menggunakan java.nio.file.Paths (Paths.get (pertama, lebih ...)) untuk dir untuk dir dan dir ke nama file bergabung.
magiccrafter

6
@ jpabluz 'Masalah dengan kinerja'! Apakah kamu serius? Mengingat penggunaan nama file dimasukkan ke dalam disk, dampak runtime dari terjemahan sama sekali tidak signifikan. Ini harus didukung oleh JVM apa pun, karena ini adalah bagian dari spesifikasi File.
Marquis dari Lorne

316

Anda menggunakannya File.separatorkarena suatu hari program Anda mungkin berjalan pada platform yang dikembangkan di tanah yang jauh, tanah yang aneh dan orang-orang asing, di mana kuda menangis dan sapi mengoperasikan semua lift. Di negeri ini, orang secara tradisional menggunakan karakter ":" sebagai pemisah file, dan dengan patuh JVM mematuhi keinginan mereka.


4
Yup, Pointy benar-benar membawa kami ke elbonia (harap dia tidak punya potongan rambut runcing ;-) (geek pun di dalam)
Riduidel

4
"... dan sapi mengoperasikan semua lift." Aku juga tidak menyesap kopiku ketika membaca itu. Cemerlang.
TJ Crowder

8
Di negara seperti itu Anda akan menggunakan kelas org.apache.chicken.elevators.OperatorUtility baru, yang menyematkan semua kegilaan ini untuk kenyamanan Anda.
Brain

27

Meskipun menggunakan File.separator untuk referensi nama file berlebihan (bagi mereka yang membayangkan tanah jauh, saya membayangkan implementasi JVM mereka akan menggantikan /dengan :seperti windows jvm menggantikannya dengan a \).

Namun, kadang-kadang Anda mendapatkan referensi file, bukan membuatnya, dan Anda perlu menguraikannya, dan untuk dapat melakukan itu, Anda perlu mengetahui pemisah pada platform. File.separator membantu Anda melakukan itu.


11

OK, mari kita periksa beberapa kode.
File.javabaris 428 hingga 435 di File.<init>:

String p = uri.getPath();
if (p.equals(""))
    throw new IllegalArgumentException("URI path component is empty");

// Okay, now initialize
p = fs.fromURIPath(p);
if (File.separatorChar != '/')
p = p.replace('/', File.separatorChar);

Dan mari kita baca fs/*(FileSystem)*/.fromURIPath()dokumen:

java.io.FileSystem
public abstract String fromURIPath (String path)
Post-process string URI path yang diberikan jika perlu. Ini digunakan pada win32, misalnya, untuk mengubah "/ c: / foo" menjadi "c: / foo". String path masih memiliki pemisah slash; kode dalam kelas File akan menerjemahkannya setelah metode ini kembali.

Ini berarti FileSystem.fromURIPath()apakah pemrosesan posting pada jalur URI hanya di Windows, dan karena di baris berikutnya:

p = p.replace('/', File.separatorChar);

Ini menggantikan setiap '/' dengan ketergantungan sistem seperatorChar, Anda selalu dapat memastikan bahwa '/' aman di setiap OS.


8

Yah, ada lebih banyak OS daripada Unix dan Windows (Perangkat portabel, dll), dan Java dikenal dengan portabilitasnya. Praktik terbaik adalah menggunakannya, sehingga JVM dapat menentukan mana yang terbaik untuk OS itu.


Sebagian besar OS tersebut menjalankan beberapa varian UNIX. :Pemisah gaya Mac lama telah lama hilang. Tampaknya semua orang kecuali Windows menggunakan standar /lagi. Dan bahkan windows tampaknya menangani garis miring dengan baik sekarang. Coba cd /windows/systempada sistem Windows 10 dari drive sistem utama Anda. Meskipun Anda masih ingin menampilkan jalur menggunakan pemisah sistem (agar tidak membingungkan pengguna Anda), Anda bisa menggunakan garis miring di /tempat lain dan yakin bahwa kode Anda akan berfungsi di mana saja yang kemungkinan akan Anda gunakan.
Shadow Man

7

Meskipun tidak ada banyak perbedaan di jalan masuk, itu tidak di jalan kembali.

Tentu Anda dapat menggunakan '/' atau '\' di File baru (String path), tetapi File.getPath () hanya akan memberi Anda salah satunya.


Koreksi sedikit ... Pada Windows Anda dapat menggunakan garis miring maju /atau mundur \\ . Tetapi di tempat lain, Anda sebaiknya menggunakan garis miring /atau Anda akan memiliki masalah.
Shadow Man

6

Terlambat ke pesta. Saya menggunakan Windows 10 dengan JDK 1.8 dan Eclipse MARS 1.
Saya menemukan itu

getClass().getClassLoader().getResourceAsStream("path/to/resource");

bekerja dan

getClass().getClassLoader().getResourceAsStream("path"+File.separator+"to"+File.separator+"resource");

tidak bekerja dan

getClass().getClassLoader().getResourceAsStream("path\to\resource");

tidak bekerja. Dua yang terakhir setara. Jadi ... Saya punya alasan bagus untuk TIDAK menggunakan File.separator.


6
Di baris ini getClass().getClassLoader().getResourceAsStream("path\to\resource");, ada tabulasi ( \t) dan carriage return ( \r).
Stephan

9
Itu skenario yang berbeda dengan pertanyaan. Metode getResourceAsStream ClassLoader tidak mengambil lintasan File, tetapi nama sumber daya yang mungkin atau mungkin tidak ada di sistem file dan didokumentasikan hanya menerima '/' sebagai pemisah jalur sumber daya.
daiscog

@Stephan tidak ada yang lucu melarikan diri di sana, karena File.separatorbackslash. Ini hanya dalam string hard-coded di mana ia diperlakukan sebagai karakter pelarian di mana Anda harus melarikan diri backslash. Jika Anda menyimpan karakter dalam file teks, atau dalam charatau Stringkemudian Anda tidak perlu menghindarinya untuk kedua kalinya karena sudah dikonversi ke karakter backslash yang diharapkan. Coba ini untuk melihat sendiri:String backslash = "\\"; System.out.println("welcome" + backslash + "to" + backslash + "reality");
Shadow Man

2
@Sthan, oh, begitu ... Anda tadi berbicara tentang baris ke-3. Anda benar. Pada baris itu (string yang dikodekan keras) Anda harus keluar dari karakter escape. Mataku berhenti di garis ke-2 dan aku bahkan tidak melihat garis ke-3 pada awalnya.
Shadow Man

3

portabilitas polos dan sederhana.


Ya, untuk portabilitas, jangan tidak menggunakan garis miring terbalik. Gunakan garis miring /atau pemisah sistem File.separator. Keduanya tampaknya bekerja di mana-mana. Meskipun File.separatordijamin bekerja di mana-mana, tebasan sederhana /juga tampaknya berfungsi di mana-mana. Jika itu tidak berhasil di suatu tempat, maka saya ingin mendengarnya. Saya percaya ini akan bekerja pada semua sistem. Paling tidak, saya belum menemukan tempat yang /tidak berfungsi (Mac OSX, Windows, * nix, Android, iOS - Saya belum memeriksa pra OSX Mac yang menggunakan ":" sebagai pemisah, OS / 2, NeXT, atau OS lain yang benar-benar kuno).
Shadow Man

1

"Java SE8 for Programmer" mengklaim bahwa Java akan mengatasi keduanya. (hlm. 480, paragraf terakhir). Contohnya mengklaim bahwa:

c:\Program Files\Java\jdk1.6.0_11\demo/jfc

akan menguraikan baik-baik saja. Perhatikan pemisah terakhir (gaya Unix).

Ini norak, dan mungkin rawan kesalahan, tapi itulah yang mereka (Deitel dan Deitel) klaim.

Saya pikir kebingungan untuk orang, daripada Jawa, adalah alasan yang cukup untuk tidak menggunakan fitur (salah?) Ini.


1

Ketika para pria menggambarkan perbedaan dengan detail varian.

Saya ingin merekomendasikan penggunaan Apache Commons io api, kelas FilenameUtilsketika berhadapan dengan file dalam suatu program dengan kemungkinan penggelaran pada banyak OS.


0

Pathname untuk file atau direktori ditentukan menggunakan konvensi penamaan sistem host. Namun, kelas File mendefinisikan konstanta tergantung platform yang dapat digunakan untuk menangani nama file dan direktori dengan cara platform-independen.

Files.seperator mendefinisikan karakter atau string yang memisahkan direktori dan komponen file dalam nama path. Pemisah ini adalah '/', '\' atau ':' untuk Unix, Windows, dan Macintosh.


":" Untuk Macintosh adalah kuno. Sejak OSX, Mac juga menggunakan "/" (forward slash) karena menjalankan bentuk UNIX dengan sistem file UNIX standar di bawah tenda.
Shadow Man


0

Menggunakan File.separator membuat Ubuntu menghasilkan file dengan "\" pada namanya, bukan direktori. Mungkin saya malas dengan cara saya membuat file (dan direktori) dan bisa menghindarinya, bagaimanapun, gunakan "/" setiap kali untuk menghindari file dengan "\" pada namanya


0

Jika Anda mencoba membuat File dari beberapa path yang siap (disimpan dalam database, misalnya) menggunakan pemisah Linux, apa yang harus saya lakukan?

Mungkin hanya menggunakan jalur buat file:

new File("/shared/folder/file.jpg");

Tetapi Windows menggunakan pemisah yang berbeda ( \). Jadi, apakah alternatifnya mengkonversi slash separator ke platform independen? Suka:

new File(convertPathToPlatformIndependent("/shared/folder"));

Metode ini convertPathToPlatformIndependent mungkin akan memiliki semacam split oleh "/" dan bergabung dengan File.separator.

Nah, bagi saya, itu tidak baik untuk bahasa yang platform independen (kan?) Dan Java sudah mendukung penggunaan /di Windows atau Linux. Tetapi jika Anda bekerja dengan jalur dan perlu mengingat konversi ini setiap kali ini akan menjadi mimpi buruk dan Anda tidak akan memiliki keuntungan nyata untuk aplikasi di masa mendatang (mungkin di alam semesta yang dijelaskan @Pointy).

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.