Pertanyaan File baru ("") vs. File baru ("."): Fitur atau Bug?


new File("") dan new File(".") menghasilkan jalur kanonik yang sama, namun objek sebelumnya tidak dapat digeser. Pertimbangkan kode di bawah ini, dan bagaimana kedua objek mengembalikan jalur kanonis yang sama. Dokumentasi menyatakan jalur kanonik adalah "keduanya mutlak dan unik". Namun hanya File yang dibuat dengan "." Argumen sebenarnya dapat digunakan.

Bukankah seharusnya pengecualian dibuang pada titik tertentu? Entah dalam panggilan konstruktor string kosong (karena objek yang dibuat tidak tampak valid), atau setidaknya di getCanonicalPath (yang setidaknya menyatakan IOException)?

import java.io.File;
import java.io.IOException;

public abstract class Test {

    public static void main(String[] args) throws Exception {
        testFile("");
        testFile(".");
    }

    private static void testFile(String arg) throws IOException {
        System.out.format("File constructor argument: \"%s\"\n", arg);
        File g = new File(arg);
      System.out.format("toString()            = \"%s\"\n", g.toString());
        System.out.format("getAbsolutePath()     = \"%s\"\n", g.getAbsolutePath());
        System.out.format("getAbsoluteFile()     = \"%s\"\n", g.getAbsoluteFile());
        System.out.format("getgetCanonicalPath() = \"%s\"\n", g.getCanonicalPath());
        System.out.format("getgetCanonicalFile() = \"%s\"\n", g.getCanonicalFile());
        System.out.format("exists()              = %s\n", g.exists());
        System.out.format("isDirectory()         = %s\n", g.isDirectory());
        System.out.println();
  }
}

Dan output yang dihasilkannya:

File constructor argument: ""
toString()            = ""
getAbsolutePath()     = "C:\usr\workspace\Test"
getAbsoluteFile()     = "C:\usr\workspace\Test"
getgetCanonicalPath() = "C:\usr\workspace\Test"
getgetCanonicalFile() = "C:\usr\workspace\Test"
exists()              = false
isDirectory()         = false

File constructor argument: "."
toString()            = "."
getAbsolutePath()     = "C:\usr\workspace\Test\."
getAbsoluteFile()     = "C:\usr\workspace\Test\."
getgetCanonicalPath() = "C:\usr\workspace\Test"
getgetCanonicalFile() = "C:\usr\workspace\Test"
exists()              = true
isDirectory()         = true

32
2018-05-04 13:00


asal


Jawaban:


Saat menggunakan konstruktor dengan String kosong, Anda membuat instance File yang memiliki dua properti:

  • Itu sebenarnya tidak ada.
  • Pathname absolutnya adalah "pathname abstrak kosong"

Saat menggunakan File ("."), Anda membuat file yang berbeda:

  • Itu ada di sistem file
  • Pathname absolutnya berisi "." karakter

File kedua ini ada, bukan yang pertama. File kedua adalah satu-satunya yang seharusnya menghormati aturan yang dijelaskan di getCanonicalPath:

Setiap pathname yang menunjukkan file atau direktori yang ada memiliki bentuk kanonik yang unik.

Karena file pertama tidak nyata, fakta bahwa jalur kanonis mereka sama tidak berarti.

Konsekuensinya, behviour yang Anda tunjuk bukan bug. Itu yang kami harapkan dari JVM.

Anda akan menemukan semua info di javadoc


14
2018-05-04 13:53



Dengan melewatkan string kosong ke konstruktor, Anda membuat 'pathname abstrak' kosong. Dari java.io.File Javadoc:

Jika string yang diberikan kosong   string, maka hasilnya kosong   nama path abstrak.

'Pathname abstrak kosong' dalam hal ini tidak ada secara fisik, karenanya exists() mengevaluasi ke false. Alasan Anda mendapatkan direktori untuk string kosong dijelaskan dalam Javadoc dari getAbsolutePath:

Jika nama path abstrak ini kosong   pathname abstrak maka nama path   string direktori pengguna saat ini,   yang dinamai oleh properti sistem   user.dir, dikembalikan.


9
2018-05-04 13:31



Menurut javaDocs:

Setiap pathname yang menunjukkan file atau direktori yang ada memiliki bentuk kanonik yang unik.

Dalam contoh pertama Anda, Anda mengacu pada "file yang tidak memiliki nama".

Seperti yang tidak ada, saya tidak berpikir itu bug File baru ("") dan File baru (".") Menghasilkan jalur kanonik yang sama.


5
2018-05-04 13:18