2015-02-02 15 views
5

Chcę przetestować, czy plik istnieje na podłączonym dysku sieciowym.Java - sprawdź, czy plik istnieje na dysku sieciowym

Napisałem ten prosty kod używając File.exists.

import java.io.File; 

public class NetworkDrive { 
    public static void main(String[] args) { 
     System.err.println(new File("/Volumes/DATA/testedFile.txt").exists()); 
    } 
} 

Działa poprawnie głównie, ale znalazłem przypadek skrajny, w którym ten kod jest problematyczny. Jeśli dysk został podłączony i z jakiegoś powodu połączenie sieciowe uległo awarii, program zawiesza się na bardzo długi czas (10 minut).

time java NetworkDrive 
false 

real 10m6.114s 
user 0m0.431s 
sys 0m0.949s 

Nawet jeśli próbuję go zabić korzystania z sygnałem KILL, proces nadal działa.

1875 ttys000 0:00.00 (java) 

Problemem jest samo z java.nio:

Files.exists(Paths.get("/Volumes/DATA/testedFile.txt")); 

używam java 1.8.0_20 wersji na OS X Yosemite.

+0

Chociaż nie powinno to zbytnio zmienić, czy próbowałeś z 'java.nio.file.Files # exists()'? – fge

+0

@fge, tak. To był mój pierwszy niepewny. – gontard

+0

Więc trzymaj się pliku java.nio.file. To jest 2015, powinieneś upuścić Plik i tak – fge

Odpowiedz

3

Metoda nr pliku istnieje w java jest tylko opakowaniem wokół natywnego wywołania O/S, co trwa tak długo. Moją sugestią byłoby wprowadzenie limitu czasu w twoim programie; zakładając, że plik nie istnieje, jeśli połączenie nie powróci w krótszym czasie. Simple timeout in java zwraca uwagę na możliwy sposób robienia tego.

EDYCJA: Fakt, że nie można zabić wątku nawet z sygnałem KILL, pokazuje, że wywołanie systemowe jest nieprzerywalne. Jest to problem O/S i nie można go rozwiązać w Javie. Chociaż uniemożliwia to zakończenie programu podczas trwania połączenia (nawet jeśli oznaczysz wątek jako demona), możesz nadal pracować nad nim, wykonując połączenie w innym wątku: w ten sposób możesz założyć, że połączenie nie powiodło się po skrócony limit czasu w głównym wątku i kontynuacja wykonywania programu, nawet jeśli połączenie jest nadal uruchomione w tle.

+0

Tak, próbowałem uruchomić ten kod w innym wątku z limitem czasu. Działa ... głównie. Ale na przykład wątek nie odpowiada, więc nie mogę zamknąć aplikacji. – gontard

+1

Zaznacz wątek jako demaen. –

+0

@DavidZimmerman odnosi się do wątków demona, co nie przeszkodzi w wychodzeniu JVM. Możesz to zrobić, przekazując właściwości ThreadFactory zdefiniowane w http://stackoverflow.com/q/7158587/1980909 jako drugi argument do wywołania 'Executors # newScheduledThreadPool' w prostym przykładzie limitu czasu. –

1

Klasa plików zależy w dużym stopniu od lokalnego systemu plików, nie wiedząc o istnieniu jakiejś sieci. Jeśli chcesz zachować szybkość reakcji aplikacji, możesz spróbować zadzwonić pod numer new File("/Volumes/DATA/testedFile.txt").exists() z innego numeru Thread.

Mam nadzieję, że to pomoże.

+0

Oto, co próbowałem. Działa ... głównie. Ale na przykład wątek tła nie odpowiada, więc nie mogę zamknąć aplikacji. – gontard

+0

Możesz to obejść, nadając wątkowi wątek demona (setDaemon (true)). – Gimby

Powiązane problemy