Java'da getPath (), getAbsolutePath () ve getCanonicalPath () arasındaki fark nedir?


583

Ne arasındaki fark var getPath(), getAbsolutePath()ve getCanonicalPath()Java?

Ve her birini ne zaman kullanacağım?


Sadece Path.toAbsolutePath().normalize()kanonik (gerçek) yol ve mutlak yol arasında iyi bir orta zemin olduğunu unutmayın .
Eckes

Yanıtlar:


625

Şu dosya adlarını düşünün:

C:\temp\file.txt - Bu bir yol, mutlak bir yol ve kanonik bir yoldur.

.\file.txt- Bu bir yol. Ne mutlak bir yol ne de kanonik bir yol.

C:\temp\myapp\bin\..\\..\file.txt- Bu bir yol ve mutlak bir yoldur. Kanonik bir yol değil.

Kanonik bir yol her zaman mutlak bir yoldur.

Bir yoldan kanonik bir yola dönüştürme işlemi mutlak hale getirir (genellikle geçerli çalışma dizinine yapışır, örneğin ./file.txtolur c:/temp/file.txt). Bir dosyanın kurallı yolu, yolu "temizler", ..\sembolik bağlantılar gibi şeyleri kaldırır ve çözer ve çözer (unix'lerde).

Ayrıca nio.Paths ile aşağıdaki örneği not edin:

String canonical_path_string = "C:\\Windows\\System32\\";
String absolute_path_string = "C:\\Windows\\System32\\drivers\\..\\";

System.out.println(Paths.get(canonical_path_string).getParent());
System.out.println(Paths.get(absolute_path_string).getParent());

Her iki yol da aynı konuma işaret etse de, çıktı oldukça farklı olacaktır:

C:\Windows
C:\Windows\System32\drivers

11
FWIW, C:\temp\file.txtkurallı bir yol değil, geçici dizin bir dosya sistemi yazılım bağlantısı veya sabit bağlantı (NTFS'de bir bağlantı) olabilir ve file.txt yumuşak bir bağlantı olabilir. Dosya sistemlerinin dosyalara olan sabit bağlantıları ayırt edip edemeyeceğini bilmiyorum.
Lawrence Dol

1
yol, bu sorunların veya bileşenlerin herhangi birinin varlığını, yalnızca sözdizimini dikkate almaz.
escape-llc

Bunu yapar, kanonik yol (normalleştirilmiş yolun aksine) dosya sistemine vurur.
Eckes

1
Temel olarak, getAbsolutePath()bunun yerine neden kullanılması gerektiğine dair bir neden göremiyorum getCanonicalPath(). Hatta daha iyi görünüyor çünkü kanonik olan bu ../parçaları otomatik olarak çözüyor .
Scadge

Unutmayın getCanonicalPathbir IOExceptionsüre atar getAbsolutePath, eğer bu bir düşüncedir.
Terk Edilmiş Sepet

129

Bunun gibi şeyler hakkında bir fikir edinmenin en iyi yolu onları denemektir:

import java.io.File;
public class PathTesting {
    public static void main(String [] args) {
        File f = new File("test/.././file.txt");
        System.out.println(f.getPath());
        System.out.println(f.getAbsolutePath());
        try {
            System.out.println(f.getCanonicalPath());
        }
        catch(Exception e) {}
    }
}

Çıktınız şöyle bir şey olacaktır:

test\..\.\file.txt
C:\projects\sandbox\trunk\test\..\.\file.txt
C:\projects\sandbox\trunk\file.txt

Böylece, getPath()göreli olabilecek veya olmayabilecek File nesnesine dayanan yolu verir; getAbsolutePath()dosyaya mutlak bir yol verir; vegetCanonicalPath() size dosyanın benzersiz mutlak yolunu verir. Aynı dosyaya işaret eden çok sayıda mutlak yol olduğuna dikkat edin, ancak yalnızca bir kurallı yol.

Her biri ne zaman kullanılır? Neyi başarmaya çalıştığınıza bağlıdır, ancak ikisinin Filesdiskteki aynı dosyayı gösterip göstermediğini görmeye çalışıyorsanız , kurallı yollarını karşılaştırabilirsiniz. Sadece bir örnek.


7
Java'nın "mutlak" bir yolun uygulanmasını yanlış yaptığı iddia edilebilir; mutlak bir yoldaki göreli yol öğelerini gerçekten kaldırmış olmalıydı. Standart form daha sonra yoldaki tüm FS bağlantılarını veya kavşakları kaldıracaktır.
Lawrence Dol

but if you were trying to see if two Files are pointing at the same file on diskNasıl? örnek lütfen?
Asif Mushtaq

@UnKnown: Bunun için standart yolu kullanırdınız.
Lawrence Dol

67

Kısacası:

  • getPath()Filenesnenin oluşturulduğu yol dizesini alır ve göreceli geçerli dizin olabilir.
  • getAbsolutePath() yol dizesini göreceli ise geçerli dizine çözümledikten sonra tam nitelikli bir yolla sonuçlanır.
  • getCanonicalPath()geçerli dizine karşı herhangi bir bağıl yolu çözümledikten sonra yol dizesini alır ve dosya sistemini işaret ettiği dosya sistemi nesnesine başvurmak için kurallı araçları ele aldığı bir yol döndürmek için göreli yolu ( .ve ..) ve tüm dosya sistemi bağlantılarını kaldırır .

Ayrıca, her birinin karşılık gelen Filenesneyi döndüren bir File eşdeğeri vardır .


36

getPath()Filenesneyi oluşturmak için kullanılan yolu döndürür . Bu dönüş değeri çalıştırıldığı yere göre değişmez (aşağıdaki sonuçlar pencereler içindir, ayırıcılar açıkça başka bir yerde farklıdır)

File f1 = new File("/some/path");
String path = f1.getPath(); // will return "\some\path"

File dir = new File("/basedir");
File f2 = new File(dir, "/some/path");
path = f2.getPath(); // will return "\basedir\some\path"

File f3 = new File("./some/path");
path = f3.getPath(); // will return ".\some\path"

getAbsolutePath()yolu yürütme konumuna veya sürücüye göre çözer. Yani eğer çalıştırılırsa 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()sisteme bağlıdır. Yolun temsil ettiği benzersiz konumu çözecektir. Bu nedenle, yolda herhangi bir "." Varsa, bunlar genellikle kaldırılır.

Ne zaman kullanılacağına gelince. Neyi başarmaya çalıştığınıza bağlıdır. getPath()taşınabilirlik için kullanışlıdır. getAbsolutePath()dosya sisteminin konumunu bulmak için yararlıdır ve getCanonicalPath()özellikle iki dosyanın aynı olup olmadığını kontrol etmek için kullanışlıdır.


bana bununla ilgili bir örnek verebilir misin? getCanonicalPath() is particularly useful to check if two files are the same.
Asif Mushtaq

20

Başınızı döndürmek için en önemli şey, Filesınıfın Sun'ın "hiyerarşik yol adları" (temelde c:/foo.txtveya gibi bir yol /usr/muggins) olarak adlandırdığı şeyin bir görünümünü temsil etmeye çalışmasıdır . Bu nedenle, yollar açısından dosyalar oluşturursunuz. Tanımladığınız işlemlerin tümü bu "yol adı" üzerindeki işlemlerdir.

  • getPath()Dosyanın oluşturulduğu yolu ( ../foo.txt) getirir
  • getAbsolutePath()Dosyanın oluşturulduğu yolu getirir, ancak yol göreli ( /usr/bobstuff/../foo.txt) ise geçerli dizin hakkında bilgi içerir
  • getCanonicalPath() dosyaya giden mutlak yolun benzersiz bir temsilini getirmeye çalışır . Bu, ".." ve "." referanslar ( /usr/foo.txt).

Diyorum Not girişimlerini bir Canonical Yolu kurulması olmak üzere VM bir atabilir - IOException. Bu genellikle, herhangi biri başarısız olabilecek bazı dosya sistemi işlemleri gerçekleştirdiği için oluşur.


3

Nadiren kullanmam gerektiğini buluyorum getCanonicalPath(), ancak Windows'ta DOS 8.3 biçiminde bir dosya adına sahip bir Dosya verilirse, java.io.tmpdirSistem özelliği döndürürse, bu yöntem "tam" dosya adını döndürür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.