Jak sprawdzić, czy plik istnieje w Javie?


841

Jak mogę sprawdzić, czy plik istnieje, przed otwarciem go do odczytu w Javie (odpowiednik Perla -e $filename )?

Jedyne podobne pytanie na temat SO dotyczy pisania pliku, w związku z czym udzielono na nie odpowiedzi, FileWriterco oczywiście nie ma tutaj zastosowania.

Jeśli to możliwe, wolę prawdziwe wywołanie interfejsu API zwracające wartość prawda / fałsz, a nie niektóre „Wywołanie interfejsu API w celu otwarcia pliku i wychwycenia, gdy zgłasza wyjątek, w którym sprawdzane jest„ brak pliku ”w tekście”, ale mogę żyć z ten drugi.


3
Również dodać, że chcesz sprawdzić odpowiednimi uprawnieniami plików: docs.oracle.com/javase/6/docs/api/java/io/File.html java.io.File posiada metody canRead, canWriteoraz canExecuteaby sprawdzić, że .
Kirkland,

6
Należy zauważyć, że jest to niebezpieczne. System plików można zmienić w dowolnym momencie, w tym zaraz po zwróceniu metody „czy ten plik istnieje”. Ponieważ i tak musisz poradzić sobie z tą sprawą, taka metoda ma wątpliwe zastosowanie. Jeśli zamierzasz otworzyć plik, poprawnym sposobem jest otwarcie pliku i obsłużenie odpowiedniego wyjątku.
Kevin

1
@kevin ma rację, ale ma niekwestionowaną użyteczność w środowisku niejednorodnym, tak się złożyło, że potrzebowałem tego;)
DVK

@DVK: Czy korzystasz z zapobiegawczo wielozadaniowego systemu operacyjnego? Albo to, albo specjalnie zaprojektowany układ Java . Jeśli to pierwsze, jesteś w równoczesnym środowisku. Inne procesy mogą zmienić system plików spod ciebie.
Kevin

2
@kevin nie ma znaczenia, ale jest to aplikacja jednowątkowa przeznaczona do użytku osobistego. Szanse, że jego dedykowany plik zostanie jakoś utworzony / zmieniony spod niego, są niewiarygodnie niskie.
DVK

Odpowiedzi:


1341

Używanie java.io.File:

File f = new File(filePathString);
if(f.exists() && !f.isDirectory()) { 
    // do something
}

15
W niektórych przypadkach, gdy istnieje () zwróci niepoprawny wynik. Na przykład podczas korzystania z systemu plików NFS występuje problem ze starymi uchwytami plików: bugs.java.com/bugdatabase/view_bug.do?bug_id=5003595 Jest to niejasne, ale było przyczyną frustrujących błędów w kodzie produkcyjnym przed.
CAW,

22
Użyj if(f.isFile())zamiast tego.
Leon

1
pamiętaj, aby użyć filePathString.trim (), aby uniknąć białych znaków
Asim

427

Polecam używać isFile()zamiast exists(). Przez większość czasu chcesz sprawdzić, czy ścieżka wskazuje plik nie tylko, że istnieje. Pamiętaj, że exists()zwróci wartość true, jeśli ścieżka wskazuje katalog.

new File("path/to/file.txt").isFile();

new File("C:/").exists() zwróci wartość true, ale nie pozwoli na otwarcie i odczytanie z niej pliku.


1
@ ylun.ca Przykład obejmuje podkatalogi? Jeśli chcesz zapytać, czy, biorąc pod uwagę bieżący katalog/path , new File("file.txt").exists()powróci true, jeśli ścieżka jest prawidłowa pełny /path/to/file.txt, odpowiedź jest wielki nie (chyba że inny plik /path/file.txtistnieje).
Matthew

149

Używając nio w Javie SE 7,

import java.nio.file.*;

Path path = Paths.get(filePathString);

if (Files.exists(path)) {
  // file exist
}

if (Files.notExists(path)) {
  // file is not exist
}

Jeśli oba existsi notExistsreturn false, istnienie pliku nie może zostać zweryfikowany. (być może brak prawa dostępu do tej ścieżki)

Możesz sprawdzić, czy pathjest to katalog, czy zwykły plik.

if (Files.isDirectory(path)) {
  // path is directory
}

if (Files.isRegularFile(path)) {
  // path is regular file
}

Sprawdź ten samouczek Java SE 7 .


2
Jakie są zalety w porównaniu z nowym plikiem (ścieżka) .exists ()? Na palin istnieje czek
Raghu K Nair

2
@RaghuKNair java.nio.file.Files.exists()jest znacznie szybszy niż java.io.File.exists()(z mojego małego testu porównawczego na jedynym testowanym komputerze: Windows Server 2012 z Javą 1.7.0_45 x64).
Matthieu

1
Właśnie tego spróbowałem i java.nio.file.Files.exists()byłem 5 razy wolniejszy niż java.io.File.exists. (Win7 Java 1.7.0_79 - x86)
ParkerHalo

Ma to również tę wadę, że Paths.get zgłasza wyjątek, jeśli ciąg nie jest prawidłowy
Richard

46

Za pomocą Java 8:

if(Files.exists(Paths.get(filePathString))) { 
    // do something
}

2
Files.exists()bierze dwa argumenty. Zazwyczaj potrzebujesz czegoś takiego Files.exists(path, LinkOption.NOFOLLOW_LINKS ).
Mike C

1
@MikeC Zastanawiam się, która metoda zostanie wywołana bez drugiego argumentu. Docu nawet nie pokazuje na ten temat żadnych informacji.
PowerFlower

1
@PowerFlower: Istnieje tylko jedna metoda Files.exists (). Bez podania drugiego argumentu nadal wywołuje tę samą metodę. Drugi argument jest zmienną varargs i może przekazać 0 lub więcej LinkOptions.
TK8

27
File f = new File(filePathString); 

To nie utworzy pliku fizycznego. Po prostu utworzy obiekt klasy File. Aby fizycznie utworzyć plik, musisz go jawnie utworzyć:

f.createNewFile();

Więc f.exists()może być używany w celu sprawdzenia, czy taki plik istnieje, czy nie.



16

Istnieje wiele sposobów na osiągnięcie tego.

  1. W przypadku tylko dla istnienia. Może to być plik lub katalog.

    new File("/path/to/file").exists();
  2. Sprawdź plik

    File f = new File("/path/to/file"); 
      if(f.exists() && f.isFile()) {}
  3. Sprawdź katalog.

    File f = new File("/path/to/file"); 
      if(f.exists() && f.isDirectory()) {}
  4. Java 7 sposób.

    Path path = Paths.get("/path/to/file");
    Files.exists(path)  // Existence 
    Files.isDirectory(path)  // is Directory
    Files.isRegularFile(path)  // Regular file 
    Files.isSymbolicLink(path)  // Symbolic Link


14

pierwsze trafienie dla „istnieje plik Java” w google:

import java.io.*;

public class FileTest {
    public static void main(String args[]) {
        File f = new File(args[0]);
        System.out.println(f + (f.exists()? " is found " : " is missing "));
    }
}

1
Nie ma potrzeby sprawdzania, czy f! = Null przed sprawdzeniem f.istnieje, jeśli nowe słowo kluczowe zawiedzie, wygeneruje wyjątek.
Sean AO Harney

nie ma sprawdzenia, czy f! = null. f + (...) używa java.io.File.toString
po prostu ktoś

@ właściwie to używa String.valueOf(), który obsługuje wartości zerowe
GreenGiant

12

Nie rób Wystarczy złapać FileNotFoundException.System plików musi sprawdzić, czy plik i tak istnieje. Nie ma sensu robić tego wszystkiego dwa razy i kilka powodów, aby tego nie robić, takich jak:

  • podwoić kod
  • problem z oknem czasowym, w którym plik może istnieć podczas testowania, ale nie podczas otwierania lub odwrotnie, i
  • fakt, że jak pokazuje istnienie tego pytania, możesz zrobić zły test i uzyskać złą odpowiedź.

Nie próbuj odgadnąć systemu po raz drugi. To wie I nie próbuj przewidywać przyszłości. Ogólnie najlepszym sposobem sprawdzenia, czy jakikolwiek zasób jest dostępny, jest po prostu próba jego użycia.


Co jeśli chcę sprawdzać co godzinę, czy plik został zdeponowany w bezpośredniej lokalizacji. Mam projekt webMethods, który musi sprawdzić, czy określony plik został przesłany na określony dysk. Jak by to było zrobione. Powiedzmy, że chcę sprawdzać co godzinę, czy plik istnieje. Mogę użyć Java do napisania klasy, która robi to prawdopodobnie z pewnego rodzaju zegarem.
Doug Hauf

2
Złapanie wyjątku jest znacznie droższe. W moim teście sprawdzenie nowego pliku (). Istnieje () było ponad 10 razy szybsze niż wyłapanie wyjątku FileNotFoundException. Tak więc, jeśli masz scenariusz, w którym zwykle brakuje plików (takich jak pamięć podręczna dysku), wyjątek jest nieprawidłowy. Drugie zgadywanie systemu jest fajne.
Nick Frolov

1
@Gnawer Nie rozwiązałeś żadnego z podniesionych przeze mnie problemów; wyjątek jest zgłaszany tylko wtedy, gdy pliku nie można otworzyć; a operacje wykonywane raz na godzinę nie wymagają mikrooptymalizacji. Ostatnie zdanie jest nonsensowne.
user207421,

1
@DougHauf w twoim przypadku nie ma problemu, ponieważ nie próbujesz nic zrobić po sprawdzeniu istnienia. Ale OP poprosił specjalnie o sprawdzenie przed otwarciem. W takim przypadku lepiej po prostu spróbować otworzyć plik.
Dan Passaro

8

Dla mnie kombinacja zaakceptowanej odpowiedzi Seana AO Harneya i wynikowego komentarza Cort3za wydaje się najlepszym rozwiązaniem.

Użyłem następującego fragmentu kodu:

File f = new File(filePathString);
if(f.exists() && f.isFile()) {
    //do something ...
}

Mam nadzieję, że to może komuś pomóc.


4

Wiem, że jestem trochę spóźniony w tym wątku. Oto moja odpowiedź, ważna od wersji Java 7 i nowszych.

Poniższy fragment kodu

if(Files.isRegularFile(Paths.get(pathToFile))) {
    // do something
}

jest całkowicie satysfakcjonujący, ponieważ metoda isRegularFilezwraca, falsejeśli plik nie istnieje. Dlatego nie trzeba sprawdzać, czy Files.exists(...).

Pamiętaj, że inne parametry to opcje wskazujące, jak należy obsługiwać łącza. Domyślnie śledzone są dowiązania symboliczne.

Z dokumentacji Oracle Oracle


Z dokumentacji sonaru: Metoda Files.exists ma zauważalnie niską wydajność w JDK 8 i może znacznie spowolnić aplikację, gdy jest używana do sprawdzania plików, które w rzeczywistości nie istnieją. To samo dotyczy Files.notExists, Files.isDirectorya Files.isRegularFile. najlepszą alternatywą dla tego jest:path.toFile().exists()
Genaut

4

Warto również zapoznać się z Commons FileUtils https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/FileUtils.html Ma to dodatkowe metody zarządzania plikami i często lepszy niż JDK.


19
Sposób, aby nie odpowiedzieć na pytanie. Zgadzam się, że commons ma wiele przydatnych rzeczy, ale może moglibyśmy pójść o krok dalej i udzielić odpowiedzi na pytanie zadane przez OP.
demongolem

4
Dał mi dość odpowiedzi.
huczne


2

Prosty przykład z dobrymi praktykami kodowania i obejmujący wszystkie przypadki:

 private static void fetchIndexSafely(String url) throws FileAlreadyExistsException {
        File f = new File(Constants.RFC_INDEX_LOCAL_NAME);
        if (f.exists()) {
            throw new FileAlreadyExistsException(f.getAbsolutePath());
        } else {
            try {
                URL u = new URL(url);
                FileUtils.copyURLToFile(u, f);
            } catch (MalformedURLException ex) {
                Logger.getLogger(RfcFetcher.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(RfcFetcher.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

Referencje i więcej przykładów na

https://zgrepcode.com/examples/java/java/nio/file/filealreadyexistsexception-implementations


1

Jeśli chcesz sprawdzić Filew katalogudir

String directoryPath = dir.getAbsolutePath()
boolean check = new File(new File(directoryPath), aFile.getName()).exists();

i sprawdź checkwynik



1

Nie używaj konstruktora plików z ciągiem.
To może nie działać!
Zamiast tego użyj identyfikatora URI:

File f = new File(new URI("file:///"+filePathString.replace('\\', '/')));
if(f.exists() && !f.isDirectory()) { 
    // to do
}

Może nie działać, dlaczego nie? I w jaki sposób naprawia to URI?
user207421,

Mieliśmy problem. f.exists () było prawdą i nawet mogliśmy uzyskać zawartość pliku. Problem polegał na tym, że ścieżka była nieprawidłowa, ale nazwa pliku była OK, nawet to był inny plik. Zmiana wywołania konstruktora za pomocą identyfikatora URI rozwiązała problem.
iviorel,

1

File.exists()aby sprawdzić, czy plik istnieje, zwróci wartość logiczną wskazującą status operacji sprawdzania; true, jeśli plik istnieje; fałsz, jeśli nie istnieje.

File f = new File("c:\\test.txt");

if(f.exists()){
    System.out.println("File existed");
}else{
    System.out.println("File not found!");
}

0

Aby sprawdzić, możesz użyć następującego kodu:

import java.io.File;
class Test{
    public static void main(String[] args){
        File f = new File(args[0]); //file name will be entered by user at runtime
        System.out.println(f.exists()); //will print "true" if the file name given by user exists, false otherwise

        if(f.exists())
        {
             //executable code;
        }
    }
}

0

Możesz to zrobić w ten sposób

import java.nio.file.Paths;

String file = "myfile.sss";
if(Paths.get(file).toFile().isFile()){
    //...do somethinh
}

Aby wziąć pod uwagę, twoja odpowiedź ma najlepszą wydajność w porównaniu z JDK 8 File.is Exist()lub Files.isRegularFile()w niej
Cristian Chaparro A.

0

Istnieje szczególny cel zaprojektowania tych metod. Nie możemy powiedzieć, aby użyć nikogo do sprawdzenia, czy plik istnieje, czy nie.

  1. isFile () : Sprawdza, czy plik oznaczony tą abstrakcyjną nazwą ścieżki jest plikiem normalnym.
  2. istnieje () : sprawdza, czy istnieje plik lub katalog oznaczony tą abstrakcyjną nazwą ścieżki. docs.oracle.com

-5

Aby sprawdzić, czy plik istnieje, wystarczy zaimportować bibliotekę java.io. *

File f = new File(“C:\\File Path”);

if(f.exists()){
        System.out.println(“Exists”);        //if file exists
}else{
        System.out.println(“Doesn't exist”);         //if file doesn't exist
}

Źródło: http://newsdivariotipo.altervista.org/java-come-controllare-se-un-file-esiste/


2
To nic nie dodaje. To, co mówisz, zostało powiedziane w kilku odpowiedziach. Proszę nie wytwarzać hałasu.
klutt
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.