Respostas:
Considere estes nomes de arquivos:
C:\temp\file.txt
- Este é um caminho, um caminho absoluto e um caminho canônico.
.\file.txt
- Este é um caminho. Não é um caminho absoluto nem um caminho canônico.
C:\temp\myapp\bin\..\\..\file.txt
- Este é um caminho e um caminho absoluto. Não é um caminho canônico.
Um caminho canônico é sempre um caminho absoluto.
A conversão de um caminho para um caminho canônico o torna absoluto (geralmente adere ao diretório de trabalho atual, por exemplo, ./file.txt
torna-se c:/temp/file.txt
). O caminho canônico de um arquivo apenas "purifica" o caminho, removendo e resolvendo coisas como ..\
e resolvendo links simbólicos (em unixes).
Observe também o exemplo a seguir com nio.Paths:
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());
Enquanto os dois caminhos se referem ao mesmo local, a saída será bem diferente:
C:\Windows
C:\Windows\System32\drivers
C:\temp\file.txt
canônico - o diretório temporário pode ser um link flexível do sistema de arquivos ou um link físico (uma junção no NTFS), e file.txt pode ser um link flexível. Não sei se os sistemas de arquivos podem distinguir links físicos para arquivos.
getAbsolutePath()
vez de getCanonicalPath()
. Até parece melhor porque o canônico resolve essas ../
partes automaticamente .
getCanonicalPath
joga um IOException
tempo getAbsolutePath
não, se isso é uma consideração.
A melhor maneira que encontrei para experimentar coisas assim é experimentá-las:
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) {}
}
}
Sua saída será algo como:
test\..\.\file.txt
C:\projects\sandbox\trunk\test\..\.\file.txt
C:\projects\sandbox\trunk\file.txt
Portanto, getPath()
fornece o caminho com base no objeto File, que pode ou não ser relativo; getAbsolutePath()
fornece um caminho absoluto para o arquivo; egetCanonicalPath()
fornece o caminho absoluto exclusivo para o arquivo. Observe que há um grande número de caminhos absolutos que apontam para o mesmo arquivo, mas apenas um caminho canônico.
Quando usar cada um? Depende do que você está tentando realizar, mas se você está tentando ver se dois Files
estão apontando para o mesmo arquivo no disco, você pode comparar seus caminhos canônicos. Apenas um exemplo.
but if you were trying to see if two Files are pointing at the same file on disk
Quão? exemplo por favor?
Em resumo:
getPath()
obtém a cadeia de caminho com a qual o File
objeto foi construído e pode ser o diretório atual relativo.getAbsolutePath()
obtém a sequência do caminho após resolvê-la no diretório atual, se for relativo, resultando em um caminho completo.getCanonicalPath()
obtém a cadeia de caminho após resolver qualquer caminho relativo no diretório atual e remove qualquer caminho relativo ( .
e ..
) e qualquer link do sistema de arquivos para retornar um caminho que o sistema de arquivos considera os meios canônicos para referenciar o objeto do sistema de arquivos para o qual aponta.Além disso, cada um deles possui um arquivo equivalente, que retorna o File
objeto correspondente .
getPath()
retorna o caminho usado para criar o File
objeto. Esse valor de retorno não é alterado com base no local em que é executado (os resultados abaixo são para janelas, os separadores são obviamente diferentes em outros lugares)
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()
resolverá o caminho com base no local de execução ou na unidade. Portanto, se executado a partir de 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()
depende do sistema. Ele resolverá o local exclusivo que o caminho representa. Portanto, se você tiver algum "." S no caminho, eles normalmente serão removidos.
Quanto a quando usá-los. Depende do que você está tentando alcançar. getPath()
é útil para portabilidade. getAbsolutePath()
é útil para encontrar o local do sistema de arquivos e getCanonicalPath()
é particularmente útil para verificar se dois arquivos são iguais.
getCanonicalPath() is particularly useful to check if two files are the same.
O mais importante é que a File
classe tenta representar uma visão do que a Sun gosta de chamar de "nomes de caminhos hierárquicos" (basicamente um caminho como c:/foo.txt
ou /usr/muggins
). É por isso que você cria arquivos em termos de caminhos. As operações que você está descrevendo são todas operações sobre esse "nome do caminho".
getPath()
busca o caminho com o qual o arquivo foi criado ( ../foo.txt
)getAbsolutePath()
busca o caminho com o qual o arquivo foi criado, mas inclui informações sobre o diretório atual se o caminho for relativo ( /usr/bobstuff/../foo.txt
)getCanonicalPath()
tenta buscar uma representação exclusiva do caminho absoluto para o arquivo. Isso elimina a indireção de ".." e "." referências ( /usr/foo.txt
).Note que digo tentativas - ao formar um caminho canônico, a VM pode lançar um IOException
. Isso geralmente ocorre porque está executando algumas operações do sistema de arquivos, qualquer uma das quais pode falhar.
Acho que raramente preciso usar getCanonicalPath()
, mas, se for fornecido um arquivo com um nome de arquivo no formato DOS 8.3 no Windows, como a java.io.tmpdir
propriedade System retorna, esse método retornará o nome de arquivo "completo".
Path.toAbsolutePath().normalize()
qual é um bom meio termo entre o caminho canônico (real) e o caminho absoluto sozinho.