Java: caminho vs arquivo

Respostas:

153

Longa história curta:

java.io.Fileprovavelmente nunca será descontinuado / não suportado. Dito isto, java.nio.file.Pathfaz parte da java.nio.filelib mais moderna e faz tudo o que java.io.Filepode, mas geralmente de uma maneira melhor e mais.

Para novos projetos, use Path.

E se você precisar de um Fileobjeto para legado, basta chamar Path # toFile ()

Migrando do arquivo para o caminho

Esta página do Oracle destaca diferenças e mapeia java.io.File functionalityparajava.nio.file lib (including Path) functionality

Artigo de Janice J. Heiss e Sharon Zakhour, maio de 2009, discutindo o sistema de arquivos NIO.2 no JDK 7

Don Cheadle
fonte
12
Você pode ler os comentários da Oracle sobre as diferenças aqui: docs.oracle.com/javase/tutorial/essential/io/legacy.html
Josiah Yoder
4
Observe também que "Arquivos" (no plural) não está obsoleto. É essencialmente uma classe abstrata que opera nos objetos Path e executa muitos dos recursos da classe File antiga, como isDirectory () ou existe ()
Josiah Yoder
2
Agora, estou me perguntando: por que as novas caixas de diálogo File / FolderChooser no JavaFX 8 ainda usam em Filevez de Path?
piegames
2
Caminho é uma interface. Para criar uma instância, use Paths.get (nome do arquivo). Pode ser por causa da confusão de ter que gravar Files.exists (Paths.get (filename)) em vez do novo File (filename) .exists () que a API mais antiga ainda é usada.
Josiah Yoder
Pathpode ser modificado com mais facilidade para "adicionar filhos" resolve(...)ou "subir um nível" com getParent()etc., enquanto Filenão pode. Essencialmente, quando você terminar de modificar o Path, frequentemente o converterá toFile()para que possa ser enviado para métodos legados, como um FileInputStreamconstrutor.
MasterHD 27/02
18

podemos considerá-lo obsoleto?

Não, você não pode considerá-lo obsoleto, a menos e até que seja marcado no FileJavadoc.

Marquês de Lorne
fonte
14
Mesmo se este for um desses "Porque o RFC diz isso" - Respostas, eu não consideraria uma boa resposta. É bastante óbvio que o arquivo será substituído pelo caminho. Se você deseja antecipadamente, pode começar a usar o Path imediatamente e usar toFile () quando necessário.
Chris
15
@ Chris Nada jamais foi removido do JDK desde que eles mudaram o modelo de evento AWT na 1.02. Não é "óbvio". Está errado.
Marquês de Lorne
5
@ downvoters Esta resposta é essencialmente uma tautologia. Não pode estar errado. Nota: Nos cinco anos desde que escrevi essa resposta, o Java 8 apareceu posteriormente, e java.io.Fileainda não foi removido nem preterido, e ainda não há nada no Javadoc que sugira que alguma dessas coisas aconteça.
Marquês de Lorne
2
@EJP Acabei de votar em seu comentário. No entanto, não tenho certeza de que você esteja certo quando diz que a resposta é uma tautologia. A questão, que provavelmente deveria ter sido esmagada por ser "baseada em opiniões", é "podemos considerá- la obsoleta"? Bem, sim, o OP e qualquer outra pessoa pode , mas não é.
Mike roedor
@mikerodent Eu sugiro que seja apenas uma leitura intencional do que realmente é a questão. Também uma cotação parcial.
Marquês de Lorne
8

Consulte este artigo para obter mais informações - http://www.oracle.com/technetwork/articles/javase/nio-139333.html

Basicamente, file.Path será o caminho a seguir a partir de agora, mas como é amplamente conhecido o pessoal de Java tende a manter a compatibilidade retroativa, acho que é por isso que o deixou.

LordDoskias
fonte
Você poderia atualizar o link? Eu gostaria de ler este artigo.
22613 John B
Infelizmente, não consegui encontrar o artigo original na página da Oracle. Aqui está uma versão da máquina wayback
LordDoskias
1
Encontrei o artigo novamente em um link adicionado ao lado normal do Oracle para responder.
Duncan Jones
5

Vou completar a resposta muito boa de @mmcrae.

existe algum motivo para usar mais um objeto java.io.File ou podemos considerá-lo obsoleto?

As classes JDK raramente são preteridas.
Você pode ver na lista de preteridos da API do JDK 8 todas as classes preteridas desde o primeiro JDK.
Ele contém apenas uma pequena parte das classes que a documentação do Oracle e a comunidade Java desencorajam a usar.
java.util.Date, java.util.Vector, java.util.Hashtable... que são classes com tantos defeitos não estão obsoletos.
Mas por que ?
Porque conceitualmente algo de deprecatedmeios ainda existe, mas desencoraja o uso, pois certamente será removido.
Milhares de programas contam com essas classes mal projetadas.
Para essas classes, os desenvolvedores da API Java não emitem esse sinal.

A resposta de @EJPé tão correta:

Não a menos e até que seja marcado no Javadoc.

Portanto, acho que sua pergunta faria mais sentido em seus termos:
"Como temos a escolha, devemos usar java.io.Fileou java.nio.file.Pathpara novos desenvolvimentos e se a resposta for java.nio.file.Path: você poderia facilmente tirar proveito dos java.io.Fileprojetos herdados java.io.File?"

Eu acredito que um java.nio.file.Path pode fazer tudo o que um java.io.File pode fazer e muito mais.

Você tem a resposta.

Este tutorial da Oracle sobre E / S herdada confirma seu pensamento.

Antes do lançamento do Java SE 7, a java.io.Fileclasse era o mecanismo usado para a E / S do arquivo, mas tinha várias desvantagens.

Muitos métodos não lançaram exceções quando falharam; portanto, era impossível obter uma mensagem de erro útil. Por exemplo, se uma exclusão de arquivo falhasse, o programa receberia uma "falha de exclusão", mas não saberia se era porque o arquivo não existia, o usuário não tinha permissões ou havia algum outro problema.

O método de renomeação não funcionou consistentemente entre plataformas. Não havia suporte real para links simbólicos.

Foi desejado mais suporte para metadados, como permissões de arquivo, proprietário do arquivo e outros atributos de segurança.

O acesso aos metadados do arquivo foi ineficiente.

Muitos dos métodos de arquivo não foram dimensionados. Solicitar uma listagem de diretório grande em um servidor pode resultar em um travamento. Diretórios grandes também podem causar problemas de recursos de memória, resultando em uma negação de serviço.

Não foi possível escrever um código confiável que pudesse percorrer recursivamente uma árvore de arquivos e responder adequadamente se houvesse links simbólicos circulares.

Com tantas desvantagens java.io.File, não precisamos realmente de nenhuma razão para usar essa classe para novos desenvolvimentos.
E mesmo para o uso de código legado java.io.File, o Oracle fornece dicas de uso Path.

Talvez você tenha um código legado que usa java.io.File e gostaria de aproveitar a funcionalidade java.nio.file.Path com um impacto mínimo no seu código.

A classe java.io.File fornece o método toPath, que converte uma instância de arquivo de estilo antigo em uma instância de java.nio.file.Path, da seguinte maneira:

Path input = file.toPath();

Você pode tirar proveito do rico conjunto de recursos disponíveis para a classe Path.

Por exemplo, suponha que você tenha algum código que excluiu um arquivo:

file.delete();

Você pode modificar esse código para usar o método Files.delete, da seguinte maneira:

Path fp = file.toPath();
Files.delete(fp);
davidxxx
fonte
Em suma, ele / ela pode realmente considerar isso obsoleto se ela / ele quiser.
mike roedor
@mike roedor. Exatamente. Conceitualmente ela deve, embora não seja o caso em termos de Javadoc, por razões explicadas.
Davidxxx
4

Sim, mas muitas APIs existentes, incluindo as APIs padrão do Java7, ainda funcionam apenas com o Filetipo.

irreputável
fonte
8
Os objetos de caminho podem ser convertidos em objetos de arquivo usando Path.toFile () e , em seguida, use APIs padrão.
jacktrades
2
Então sua resposta é 'sim, mas não'?
Marquês de Lorne #
1

O Java.io.File não está obsoleto. Sim java.nio.file.Path é melhor, mas enquanto ainda houver muitos programas e livros de texto usando o Java.io.File, mesmo que por motivos legados, ele não deve ser considerado obsoleto, é muito importante. Fazer isso seria apenas jogar uma chave inglesa nos trabalhos, sem nenhum ganho geral. Por exemplo, a estrutura do Android usa File para alguns de seus recursos básicos de manipulação de arquivos, muitas outras coisas.

Andrew S
fonte
Ele não perguntou se Pathera melhor. Ele perguntou se Filefoi preterido.
Marquês de Lorne,
1
@EJP Acho que você está sendo um pouco pedante. O OP perguntou se o java.io.File estava obsoleto e eu respondi isso. Ele também afirmou "Acredito que um java.nio.file.Path pode fazer tudo o que um java.io.File pode fazer e muito mais". Eu estava apenas confirmando o comentário dele, que mal valeu a pena votar.
Andrew S
-9

Para novos aplicativos escritos em Java 7, existe algum motivo para usar um objeto java.io.File mais ou podemos considerá-lo obsoleto?

É como dizer: "Napoleão deveria invadir a Rússia, ou essas couves de Bruxelas são realmente saborosas?"

Quanto à segunda parte da pergunta, você pode realmente considerá-la obsoleta. Em janeiro de 2018, não foi preterido. Mas não há nada para impedi-lo de considerar isso. É impossível dizer se isso lhe proporcionará alguma vantagem nesta vida ou na próxima.

microfone roedor
fonte
5
Eu não entendo sua analogia.
Tunaki 5/03
Qualquer pergunta "ou" deve apresentar duas alternativas lógicas, as quais respondem essencialmente à mesma pergunta.
mike roedor
Desculpe, isso parece altamente pedante neste contexto. A idéia é "Eu quero usar File. Devo, sim ou não?"
Tunaki 5/03/2017
1
Sim, eu concordo que é uma pergunta carregada ... especialmente porque muitas APIs de terceiros existentes ainda usam de Filequalquer maneira. Não vai morrer tão cedo.
Tunaki 5/03
3
it isn't deprecated. But there's nothing to stop you *considering* it soRI MUITO.
Don Cheadle