Estou vendo um pedaço de código Java agora, e ele pega um caminho como uma String e obtém seu URL usando URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);
, em seguida, chama String path = resource.getPath()
e, finalmente, executa new File(path);
.
Ah, e também há chamadas para URL url = resource.toURI();
e String file = resource.getFile()
.
Estou totalmente confuso agora - principalmente por causa da terminologia, eu acho. Alguém pode me explicar as diferenças ou fornecer alguns links para materiais à prova de fictícios? Especialmente URI para URL e Recurso para Arquivo ? Para mim, parece que deveriam ser a mesma coisa, respectivamente ...
A diferença entre getFile()
e getPath()
é explicada aqui: Qual é a diferença entre url.getFile () e getpath ()? (Curiosamente, os dois parecem retornar Strings, o que provavelmente acrescenta muito ao meu estado de espírito ...)
Agora, se eu tiver um localizador que faz referência a uma classe ou pacote em um arquivo jar, esses dois (isto é, caminho e strings de arquivo) serão diferentes?
resource.toString()
lhe daria jar:file:/C:/path/to/my.jar!/com/example/
, afinal (observe o ponto de exclamação).
A diferença entre URI e URL em Java é que o primeiro não codifica espaços? Cf. Arquivos, URIs e URLs em conflito em Java (esta resposta explica a diferença conceitual geral entre os dois termos muito bem: URIs identificam e URLs localizam; )
Por último - e mais importante - por que preciso do File
objeto; por que um Resource ( URL
) não é suficiente? (E existe um objeto Resource?)
Desculpe se esta pergunta é um pouco desorganizada; apenas reflete a confusão que tenho ... :)
fonte
Path
e FileSystem de NIO :)URL
é opaco - como você mostrajar:file:
, ou seja, um recurso em um.jar
arquivo. Colocar isso em umFile
dificilmente resultará em algo útil.Respostas:
ATUALIZAÇÃO 12-04-2017 Verifique a resposta do JvR, pois contém uma explicação mais exaustiva e exata!
Note que não me considero 100% competente para responder, mas mesmo assim aqui ficam alguns comentários:
File
representa um arquivo ou diretório acessível através do sistema de arquivosURL#getPath
é getter na parte do caminho do URL (protocol://host/path?query
)URL#getFile
conforme JavaDoc retornapath+query
Em Java,
URI
é apenas uma estrutura de dados para manipular o próprio identificador genérico.URL
por outro lado, é realmente um localizador de recursos e oferece recursos para realmente ler o recurso por meio deURLStreamHandler
s registrados .URLs podem levar a recursos do sistema de arquivos e você pode construir URL para cada recurso do sistema de arquivos usando
file://
protocolo (portanto, relaçãoFile
<->URL
).Também esteja ciente de que isso
URL#getFile
não está relacionado comjava.io.File
.É o suficiente. Somente se você deseja passar o recurso para algum componente que pode trabalhar apenas com arquivos, você precisa obtê
File
-lo. No entanto, nem todos os URLs de recursos podem ser convertidos emFile
s.Do ponto de vista do JRE, é apenas um termo. Alguns frameworks fornecem essa classe (por exemplo, Spring's Resource ).
fonte
java.nio.file.Path
que é basicamente um substituto do (Java 7+)java.io.File
, já que a última API era aparentemente mal planejada nos primeiros dias do Java.A terminologia é confusa e às vezes atordoante, e principalmente nasceu da evolução do Java como uma API e como uma plataforma ao longo do tempo. Para entender como esses termos passaram a significar o que significam, é importante reconhecer duas coisas que influenciam o design do Java:
Vou examinar os conceitos e como eles surgiram. Vou responder suas outras perguntas específicas depois disso, porque posso ter que me referir a algo na primeira parte.
O que é um "Recurso"?
Um dado genérico e abstrato que pode ser localizado e lido. Em poucas palavras, Java usa isso para se referir a um "arquivo" que pode não ser um arquivo, mas representa uma parte nomeada de dados. Ele não tem uma classe direta ou representação de interface em Java , mas por causa de suas propriedades (localizável, legível), geralmente é representado por uma URL.
Como um dos primeiros objetivos de design do Java era ser executado dentro de um navegador, como um aplicativo em sandbox (applets!) Com direitos / privilégios / autorização de segurança muito limitados, o Java faz uma diferença (teórica) clara entre um arquivo (algo no local sistema de arquivos) e um recurso (algo que ele precisa ler). É por isso que a leitura de algo relativo ao aplicativo (ícones, arquivos de classe e assim por diante) é feita por meio
ClassLoader.getResource
e não por meio da classe File.Infelizmente, como "recurso" também é um termo genérico útil fora dessa interpretação, ele também é usado para nomear coisas muito específicas (por exemplo, classe ResourceBundle , UIResource , Resource ) que não são, neste sentido, um recurso.
As principais classes que representam (um caminho para) um recurso são java.nio.file.Path , java.io.File , java.net.URI e java.net.URL .
Arquivo (java.io, 1.0)
A classe File representa um recurso que pode ser acessado por meio do sistema de arquivos nativo da plataforma . Ele contém apenas o nome do arquivo, então é realmente mais um caminho (veja mais tarde) que a plataforma host interpreta de acordo com suas próprias configurações, regras e sintaxe.
Observe que Arquivo não precisa apontar para algo local , apenas algo que a plataforma host entenda no contexto de acesso ao arquivo, por exemplo, um caminho UNC no Windows. Se você montar um arquivo ZIP como um sistema de arquivos em seu sistema operacional, o Arquivo lerá suas entradas contidas perfeitamente.
URL (java.net, 1.0)
Paralelamente ao conceito de recurso, a URL representa esse recurso da mesma forma que a classe File representa um arquivo na plataforma host: como uma string estruturada que aponta para um recurso. A URL contém adicionalmente um esquema que sugere como acessar o recurso (com "arquivo:" sendo "pergunte à plataforma do host") e, portanto, permite apontar para recursos por meio de HTTP, FTP, dentro de um JAR e outros enfeites.
Infelizmente, os URLs vêm com sua própria sintaxe e terminologia, incluindo o uso de "arquivo" e "caminho". Caso a URL seja uma URL de arquivo, URL.getFile retornará uma string idêntica à string do caminho do arquivo referenciado.
Class.getResource
retorna um URL: é mais flexível do que retornar File e atendeu às necessidades do sistema imaginadas no início dos anos 90.URI (java.net, 1.4)
URI é uma (leve) abstração sobre URL. A diferença entre URI e URL é conceitual e principalmente acadêmica, mas URI é melhor definido em um sentido formal e cobre uma gama mais ampla de casos de uso. Como URL e URI são / não são a mesma coisa, uma nova classe foi introduzida para representá-los, com os métodos URI.toURL e URL.toURI para mover entre um e outro.
Em Java, a principal diferença entre URL e URI é que uma URL carrega a expectativa de ser resolvida , algo a partir do qual o aplicativo pode querer um InputStream; um URI é tratado mais como um thingamajig abstrato que pode apontar para algo resolvível (e geralmente faz), mas o que significa e como alcançá-lo são mais abertos ao contexto e interpretação.
Caminho (java.nio.file, 1.7)
A nova API de arquivo, iconificada na interface Path, permite uma flexibilidade muito maior do que a classe File poderia oferecer. A interface Path é uma abstração da classe File e faz parte da New IO File API . Onde File necessariamente aponta para um "arquivo" conforme entendido pela plataforma host, Path é mais genérico: ele representa um arquivo (recurso) em um sistema de arquivos arbitrário .
O caminho tira a confiança no conceito de arquivo da plataforma host. Pode ser uma entrada em um arquivo ZIP, um arquivo acessível por FTP ou SSH-FS, uma representação com várias raízes do classpath do aplicativo ou realmente qualquer coisa que possa ser representada de forma significativa por meio da interface FileSystem e seu driver, FileSystemProvider. Ele traz o poder de "montar" sistemas de arquivos no contexto de um aplicativo Java.
A plataforma host é representada por meio do "sistema de arquivos padrão"; quando você chama
File.toPath
, você obtém um caminho no sistema de arquivos padrão.Improvável. Se o arquivo jar é no sistema de arquivos local, você não deve ter um componente de consulta, de modo
URL.getPath
eURL.getFile
deve retornar o mesmo resultado. No entanto, escolha o que você precisa: arquivos-URLs podem não ter componentes de consulta, mas eu poderia adicionar um de qualquer maneira.URL pode não ser suficiente porque Arquivo fornece acesso a dados de manutenção, como permissões (legível, gravável, executável), tipo de arquivo (sou um diretório?) E a capacidade de pesquisar e manipular o sistema de arquivos local. Se esses forem os recursos de que você precisa, Arquivo ou Caminho os fornecerá.
Você não precisa do Arquivo se tiver acesso ao Caminho. No entanto, algumas APIs mais antigas podem exigir o arquivo.
Não, não há. Há muitas coisas com nomes semelhantes, mas não são um recurso no sentido de
ClassLoader.getResource
.fonte
A resposta de Pavel Horal é boa.
Como ele diz, a palavra "arquivo" tem significados totalmente diferentes (praticamente não relacionados) em
URL#getFile
vsjava.io.File
- pode ser que isso seja parte da confusão.Apenas para adicionar:
Um recurso em Java é um conceito abstrato, uma fonte de dados que pode ser lida. A localização (ou endereço) de um recurso é representada em Java por um
URL
objeto.Um recurso pode corresponder a um arquivo regular no sistema de arquivos local (especificamente, quando
URL
começa comfile://
). Mas um recurso é mais geral (pode ser também algum arquivo armazenado em um jar, ou alguns dados a serem lidos da rede, ou da memória, ou ...). E também é mais limitado, porque umFile
(além de ser outras coisas que um arquivo normal: um diretório, um link) também pode ser criado e gravado.Lembre-se de que em Java um
File
objeto não representa realmente "um arquivo", mas a localização (o nome completo, com o caminho) de um arquivo. Assim, umFile
objeto permite localizar (e abrir) um arquivo, assim comoURL
permite acessar (e abrir) um recurso. (Não existe nenhumaResource
classe em Java para representar um recurso, mas também não existe uma para representar um arquivo! Mais uma vez:File
não é um arquivo, é o caminho de um arquivo).fonte
Pelo que entendi, você poderia categorizá-los da seguinte forma:
Baseado na Web: URIs e URLs.
E local: Recurso, Caminho e Arquivos
Seria mais fácil se eles fossem mesclados em uma classe - eles são realmente confusos: D
Espero que isso ajude você :)
(Acabei de dar uma olhada na documentação - veja docs.oracle.com)
fonte
Um arquivo é uma representação abstrata de uma entidade no sistema de arquivos local.
Um caminho geralmente é uma string que indica a localização de um arquivo em um sistema de arquivos. Geralmente não inclui o nome do arquivo. Portanto, c: \ documents \ mystuff \ stuff.txt teria um caminho com o valor de "C: \ documents \ mystuff" Obviamente, o formato dos nomes de arquivos e caminhos absolutos variariam enormemente de sistema de arquivo para sistema de arquivo.
URL é um subconjunto de URI com URL geralmente representando recursos acessíveis por http. Não acho que haja qualquer tipo de regra rígida sobre quando algo deve ser um URI versus um URL. URIs são strings na forma de "protocol: // resource-identifier", como bitcoin: // params, http://something.com?param=value . Classes como URL geralmente envolvem a string e fornecem métodos utilitários que String não teria razão para fornecer.
Recurso não existe, pelo menos não no sentido de que você está falando. Só porque um método é denominado getResource não significa que ele retorne um objeto do tipo Resource.
Em última análise, a melhor maneira de descobrir o que os métodos de uma classe fazem é criar uma instância dela em seu código, chamar os métodos e, em seguida, avançar no modo de depuração ou enviar os resultados para System.out.
fonte