File.exists () retorna falso quando o arquivo existe


90

Eu encontrei um bug que não consigo encontrar nenhuma lógica por trás. Eu tenho este objeto File, que é criado assim:

File file = new File("utilities/data/someTextFile.txt");

Então eu faço file.exists(), e ele retorna false(!?). Se o arquivo não for encontrado, estou logando f.getAbsolutePath()em um arquivo. Quando eu olho para o caminho, parece OK. Posso copiar e colar o caminho completo na janela "Executar" do Windows e o arquivo abre corretamente.

O arquivo existe o tempo todo e não é excluído nem alterado durante a execução do meu aplicativo. Ele está localizado na máquina local.

Isso só parece ocorrer em certas situações. Posso reproduzir a falha a qualquer momento, mas tenho certeza de que o caminho do objeto de arquivo não é alterado pelas ações que faço para reproduzir a falha.

O que pode causar um file.exists()retorno falso? Isso tem algo a ver com permissões ou bloqueios de arquivos, etc.?


Portanto, é possível ler do arquivo mesmo se exists () retornar falso?
Harry Lime

sim, posso ler o arquivo mesmo se exists () retornar falso.
atsjoo

1
O que exatamente é necessário para reproduzir a falha?
user85421

1
Ele está dentro de um aplicativo que chama funções escritas em matlab e compiladas no aplicativo java. Parece que funções matlab que mudam o "diretório atual" estão causando o problema. Estou usando o caminho absoluto ao criar o objeto de arquivo, então isso não deve ser um problema - no entanto, parece ser. Obviamente, verifiquei o caminho absoluto do objeto de arquivo e ele está correto (o mesmo que estava antes de a função matlab alterar o diretório atual).
atsjoo

7
Por acaso, você está trabalhando em um diretório remoto (por exemplo, uma montagem NFS)?
Tomer Gabel

Respostas:


42

Estou vendo a seguinte situação no Windows 7:

file.exists() == false
file.getAbsoluteFile().exists() == true

O arquivo em questão é "var \ log", o caminho absoluto se refere a um arquivo existente que está em um subdiretório normal (não em uma loja virtual). Isso é visto no IDE.


16
Acabei de descobrir: bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097 Aparentemente, as operações em execução no arquivo são resolvidas no diretório atual, enquanto getAbsolutePath resolve em user.dir. Se esses dois caminhos não corresponderem, você obterá resultados conflitantes. Diabólico!
Roman Zenka

3
Eu tenho exatamente o mesmo problema que tentei usar os dois métodos para verificar se o arquivo existe, mas ainda consigo falso no Windows 7 apenas! Qualquer ideia?
Dejell de

@Odelya: Qual IDE você está usando? Como o seu -Duser.dir está definido? Meu problema foi causado pela configuração de -Duser.dir em um diretório diferente do atual.
Roman Zenka,

1
Para qualquer um que esteja trabalhando em um projeto dinâmico da Web, usar file.exists () lançará uma exceção, use file.getAbsoluteFile (). Exists () para verificar se há arquivos no diretório WEB-INF (dica geral, não específica do Windows 7 )
PS

Considere a criação de um controle de qualidade separado para esta resposta e comentários
Bato-Bair Tsyrenov

17

Parece que há uma diferença em como o caminho é especificado em Java.

Por exemplo, se o caminho do arquivo for especificado como file:/C:/DEV/test.txtthen

File f = new File(filename);
f.exists();

vai voltar false. O caminho pode funcionar no explorer ou no navegador, mas é um URL e não um caminho de arquivo absoluto.

Mas por outro lado, se o caminho do arquivo for especificado como C:/DEV/test.txtthen

File f = new File(filename);
f.exists();

retornará trueporque o caminho não é um URL, mas é um caminho absoluto.

Com o Spring Framework, é exatamente isso o que ResourceUtils.getFile(filename)faz - onde o nome pode ser uma URL ou o caminho absoluto do arquivo.


5
Eu não esperaria file:/C:/DEV/test.txtfuncionar como um nome de caminho. É um URL, não um nome de caminho. Embora algumas pessoas cometam esse erro, não há evidências de que o OP tenha ...
Stephen C

15

Se o processo não tiver permissão para informar se um arquivo existe, ele retornará falso. Pode ser possível abrir um arquivo, mas não saber por métodos normais se ele existe.


20
Interessante. Você pode expandir isso? Quais permissões específicas você tem em mente?
Clément de

Aqui pode ser a capacidade de bloqueio de java.nio.file.AccessDeniedException para alcançar a existência de arquivo / dir. Por exemplo, se você mantiver o dir aberto no FAR ou outro explorador de arquivos, exclua o dir com todos os arquivos aninhados e verifique a existência desse diretório, então você pode obter AccessDeniedException (estende IOException) para o arquivo temporário mantido para você. Nesse caso, Files.exists retorna false para IOException.
beluha de

11

As respostas acima não ajudaram no meu caso. Conforme declarado acima, eu tinha:

file.exists() => false
file.getAbsoluteFile().exists => true

A causa raiz disso foi que o proprietário da máquina com Windows 7 modificou o registro do CMD para que um comando fosse executado automaticamente em um diretório específico para funcionar com Python. Essa modificação incapacitou o código Java 1.6 que aparentemente usa CMD no Windows para certas operações de arquivo, como exists(). Eliminar a execução automática do registro resolveu o problema.


1
3,5 anos depois, tive o mesmo problema. Eu tinha um script de execução automática configurado para configurar variáveis ​​de ambiente cada vez que iniciei cmd.com. Ele nem mesmo mudou o diretório atual - apenas algumas macros doskey e algumas variáveis ​​de ambiente. Removi a execução automática e apenas executei manualmente os comandos no arquivo e, de repente, File.exists () funciona corretamente.
Homr Zodyssey

1
OMG, realmente funciona (os dois), eu estava apenas checando estupidamente o arquivo errado e me deparei com essa pergunta para descobrir por que nenhum deles funciona para mim :) BTW, parece que ()estão faltando na segunda linha depois exists; )
RAM237

3

Obviamente, existem várias causas possíveis e as respostas anteriores as documentam bem, mas aqui está como resolvi isso em um caso específico:

Um aluno meu teve esse problema e eu quase arranquei meu cabelo tentando descobrir. Descobriu-se que o arquivo não existia, embora parecesse que sim. O problema era que o Windows 7 estava configurado para "Ocultar as extensões dos tipos de arquivo conhecidos". Isso significa que se o arquivo parece ter o nome "data.txt", seu nome de arquivo real é "data.txt.txt".

Espero que isso ajude outras pessoas a economizar algum cabelo.


Não acho que seja esse o problema no meu caso. Como mencionei na minha pergunta: "Posso copiar e colar o caminho completo na janela" Executar "do Windows e o arquivo abre perfeitamente.", O que significa que o arquivo realmente existe.
atsjoo

3

O new Filecomando apenas cria uma instância de um arquivo usando o nome de caminho fornecido. Na verdade, ele não cria um arquivo no disco rígido.

Se você diz

File file = new File ("path");
file.exists() 

Isso pode retornar verdadeiro apenas se houver um arquivo existente com o mesmo caminho. Se você pretendia verificar o mesmo arquivo declarado na primeira linha, pode ser necessário usá-lo dessa forma.

File file = new File ("path");
file.createNewFile();
file.exists();

Agora, isso vai voltar verdadeiro.


pequena explicação: cada chamada ao construtor pelo uso de nova palavra-chave cria um objeto - o mesmo que neste caso um objeto descrito por Class cujo nome é Arquivo! portanto, não é uma instância de File! = descriptors :)
ceph3us

3

Se você não quiser lidar com chamadas getAbsoluteFile () cada vez que precisar chamar um método, é melhor criar sua instância de arquivo já com um caminho absoluto. Isso deve resolver o problema:

File file = new File("utilities/data/someTextFile.txt").getAbsoluteFile();

Eu sugiro cercá-lo com um bloco try-catch, BTW.


3

Para generalizar o problema, o problema surge durante a conversão de URL / URI em caminhos locais.

Example: URL url = file:/D:/code%20repo%20sample/sample.txt

// To remove url reference
String localPath = url.getPath();  
> /D:/code%20repo%20sample/sample.txt

// Decoding reserved characters in url from hexadecimal to character
URLDecoder.decode(localPath, StandardCharsets.UTF_8.toString()); 
> /D:/code repo sample/sample.txt

Espero que isto ajude.


2

Quando ["Ocultar as extensões dos tipos de arquivo conhecidos."] Está marcado, o windows abre "t.txt.txt" ao digitar "t.txt" no [explorer] / [run windows], mas não programaticamente.


1
Eu tive esse problema, e o problema é que criei um arquivo txt, que se chamava 'testFile.txt', em C: \ test. Eu me referi a esse arquivo usando o caminho C: \ test \ testFile.txt, que não funcionou. Foi porque o arquivo foi realmente salvo como testFile.txt.txt, daí o voto favorável na solução acima (pergunta antiga, mas nenhuma resposta aceita!)
Theblacknight

Deus, o Windows é uma merda.
aafc

0

Boas respostas a todos. Descobri que isso parece ser um problema com o acesso do Java ao C:diretório raiz no Windows. Qualquer outro diretório deve servir, mas por algum motivo, especificamente mencionando C:\ou C:ou C:/pode apresentar um erro. Resolvi este problema muito semelhante bloqueando a menção new File("C:");e substituindo-a por new File(System.getProperty("file.separator"));ou você deve ser capaz de codificar "\" em vez de dizer "c:" como seu diretório de arquivo e pode funcionar. Não é elegante, mas fez o trabalho para mim neste projeto.

Espero que ajude. Pode não ser a solução certa, mas pelo menos funcionou para mim. Eu estou em JRE 1.6, Win 7. Felicidades!

Respeitosamente,

@ Carpenter1010


0

Se as situações de falha envolverem executá-lo como outro usuário e você estiver no Windows Vista / Windows 7, pode ser causado pelo VirtualStore, o mecanismo pelo qual o Windows permite que um usuário sem privilégios "escreva" em locais que normalmente não pode. No entanto, as alterações são armazenadas em "% USERPROFILE% \ AppData \ Local \ VirtualStore \", que são privadas para cada conta de usuário.


1
Estou executando no windows xp x86
atsjoo

0

Quando nada de cima funcionou para mim, tentei

filePath = filePath.trim();

Isso irá limpar sua string de qualquer caractere indesejado


0

Recentemente me deparei com esse mesmo problema. O que fiz foi desinstalar o Netbeans, excluir a pasta netbeans da unidade C, arquivos de programa, atualizar, programData, virtualmente em todos os lugares. Em seguida, reinstale. Agora está funcionando bem. Não se esqueça de fazer backup da pasta do projeto netbeans antes de realizar as ações acima.

Espero que ajude.


0

Com algum IDE (pode ser) e / ou com algum SO (ex: janela), por padrão eles não têm acesso de gravação nos arquivos. Portanto, se você tentar fazer file.exists (), será exibido false. a fim de consertar isso, faça como abaixo

se sua variável ref para Arquivo for f, exemplo: Arquivo f = novo Arquivo ("caminho");

então, para fazê-lo funcionar, selecione f com o mouse e vá para o menu Pesquisar> Acesso de gravação> Área de trabalho. Espero que funcione.


-2

Acho que você deveria usar barra invertida, assim:

File file = new File ("C: \\ User \\ utilities \\ data \\ someTextFile.txt"); (duas barras invertidas, não é um erro de digitação)

Deve resolver o problema :)


3
Acho que o problema está mais relacionado ao caminho absoluto do que ao caminho relativo. A barra é válida em Java, mesmo para caminhos do Windows.
рüффп
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.