2009-05-28 18 views
64

Napotkałem błąd, którego nie mogę znaleźć za żadną logiką. Mam ten obiekt File, który jest tworzony tak: (!?)File.exists() zwraca wartość false, gdy plik istnieje

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

I wtedy zrobić file.exists() i zwraca false. Jeśli plik nie zostanie znaleziony, loguję się do pliku f.getAbsolutePath(). Kiedy patrzę na ścieżkę, wydaje mi się, że jest OK. Mogę skopiować i wkleić pełną ścieżkę do okna "Uruchom" w Windows, a plik otworzy się dobrze.

Plik istnieje cały czas i nie jest usuwany ani zmieniany podczas działania mojej aplikacji. Znajduje się na lokalnym komputerze.

To zdaje się zdarzać tylko w pewnych sytuacjach. Mogę odtworzyć błąd w dowolnym momencie, ale jestem pewien, że ścieżka pliku pliku nie zostanie zmieniona przez działania, które wykonuję, aby odtworzyć błąd.

Co może spowodować, że file.exists() zwróci false? Czy ma to coś wspólnego z uprawnieniami lub blokadami plików itp.?

+0

Czy możliwe jest odczytanie z pliku, nawet jeśli istnieje() zwraca false? –

+0

tak, mogę odczytać z pliku, nawet jeśli istnieje() zwraca false. – atsjoo

+0

Czy próbowałeś różnych JVM? Różne maszyny? Różne systemy operacyjne? –

Odpowiedz

15

Jeśli proces nie ma uprawnień do określenia, czy plik istnieje, zwróci wartość false. Możliwe, że można otworzyć plik, ale nie można go rozpoznać po normalnych metodach, jeśli istnieje.

+18

Interesujące. Czy możesz rozwinąć to? Jakie konkretne uprawnienia masz na myśli? –

+0

Tutaj może istnieć możliwość blokowania java.nio.file.AccessDeniedException w celu osiągnięcia dostępu do pliku/katalogu. Na przykład, jeśli otworzysz dir w FAR lub innym eksploratorze plików, usuniesz katalog z wszystkimi zagnieżdżonymi plikami i sprawdzisz istnienie tego katalogu, możesz uzyskać AccessDeniedException (rozszerza wyjątek IOException) dla pliku tymczasowego przechowywanego dla ciebie. W tym przypadku Files.exists zwraca false dla IOException. – AlfaFire

0

Jeśli sytuacja, w której się nie powiedzie, polega na uruchomieniu go jako innego użytkownika i na systemie Windows   Vista/Windows   7, może to być spowodowane przez mechanizm VirtualStore, mechanizm, w którym system Windows umożliwia nieuprzywilejowanemu użytkownikowi "zapisanie" umieszczenia go normalnie nie może. Zmiany są jednak przechowywane w "% USERPROFILE% \ AppData \ Local \ VirtualStore \", które są prywatne dla każdego konta użytkownika.

+1

Używam Windows XP x86 – atsjoo

25

widzę następującą sytuację w systemie Windows 7:

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

dany plik jest „var \ log”, bezwzględna ścieżka odnosi się do istniejącego pliku, który znajduje się w normalnym podkatalogu (nie sklep wirtualny). Widać to z IDE.

+14

Po prostu wymyśliłem: http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097 Wygląda na to, że operacje na aktach są rozwiązywane w bieżącym katalogu, a getAbsolutePath działa na user.dir. Jeśli te dwie ścieżki nie są zgodne, otrzymasz sprzeczne wyniki. Diabelski! –

+2

Mam dokładnie ten sam problem Próbowałem użyć obu metod, aby sprawdzić, czy plik istnieje, i nadal otrzymuję fałsz tylko na Windows 7! Dowolny pomysł? – Dejell

+0

@Odelya: Z jakiego IDE korzystasz? Do czego jest ustawiony twój plik -Duser.dir? Mój problem został spowodowany przez ustawienie -Duser.dir na inny katalog niż bieżący działający. –

1

Kiedy ["Ukryj rozszerzenia dla znanych typów plików."] Jest zaznaczone, okna otwierają się "t.txt.txt", gdy wpisz "t.txt" w [eksploratorze]/[uruchom okno], ale programowo nie.

+1

Miałem ten problem, a problem polegał na tym, że utworzyłem plik txt, który nazywał się "testFile.txt", w C: \ test. Odniosłem się do tego pliku, używając ścieżki C: \ test \ testFile.txt, która nie działała. To dlatego, że plik został faktycznie zapisany jako plik testowy.txt.txt, stąd też głosowanie nad powyższym rozwiązaniem (stare pytanie, ale nie ma akceptowanej odpowiedzi!) – Theblacknight

+0

Bóg Windows jest tak niesmaczny. – aafc

11

Wygląda na to, że istnieje różnica w sposobie określania ścieżki w Javie.

Na przykład, jeżeli plik ścieżki jest określone jako file:/C:/DEV/test.txt następnie

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

powróci false. Ścieżka może działać w eksploratorze lub w przeglądarce, ale jest to adres URL, a nie bezwzględna ścieżka do pliku.

Ale z drugiej strony, jeśli ścieżka do pliku jest określona jako C:/DEV/test.txt następnie

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

powróci true ponieważ ścieżka nie jest adresem URL, ale jest to ścieżka bezwzględna.

Z Spring Framework to jest dokładnie to, co robi ResourceUtils.getFile(filename) - gdzie nazwa może być adresem URL lub bezwzględną ścieżką pliku.

+1

Nie oczekuję, że plik 'file:/C:/DEV/test.txt' będzie działał jako nazwa ścieżki. To adres URL, a nie nazwa ścieżki. Podczas gdy niektórzy ludzie popełniają ten błąd, nie ma dowodów, że OP ... –

8

Powyższe odpowiedzi nie pomogły w moim przypadku.Jak wspomniano powyżej, miałem:

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

Przyczyną tego było to, że właściciel 7 maszyna Okna był modyfikowany rejestru dla CMD tak, że to autorun polecenie do uruchomienia w określonym katalogu do pracy z Pyton. Ta modyfikacja okaleczyła kod Java 1.6, który najwyraźniej używa CMD na Windows dla pewnych operacji na plikach, takich jak exists(). Wyeliminowanie autorun z rejestru rozwiązało problem.

+1

3.5 lat później, i wpadłem na ten sam problem. Miałem skrypt autorun skonfigurowany do konfigurowania zmiennych środowiskowych za każdym razem, gdy uruchomiłem cmd.com. Nie zmienił nawet bieżącego katalogu - tylko niektóre makra doskey i niektóre zmienne środowiskowe. Usunąłem autorun i po prostu ręcznie uruchomiłem polecenia w pliku i nagle File.exists() działa poprawnie. –

+1

OMG, to naprawdę działa (obaj), byłem po prostu głupio sprawdzając niewłaściwy plik i natknąłem się na to pytanie, aby dowiedzieć się, dlaczego żaden z nich nie działa dla mnie :) BTW, wydaje się, że '()' brakuje w druga linia po "istnieniu";) – RAM237

0

Dobre odpowiedzi dla wszystkich. Odkryłem, że to problem z dostępem do katalogu głównego C: w systemie Windows. Każdy inny katalog powinien być w porządku, ale z jakiegoś powodu, wymienienie C:\ lub C: lub C:/ może spowodować błąd. Rozwiązałem ten bardzo podobny problem, uwalniając wzmiankę o new File("C:"); i zastępując ją nowym File(System.getProperty("file.separator")); lub powinieneś być w stanie napisać "\" zamiast "c:" jako swój katalog plików i może się to udać. Nie elegancko, ale wykonano dla mnie zadanie związane z tym projektem.

Mam nadzieję, że to pomaga. Być może nie jest to właściwe rozwiązanie, ale przynajmniej zadziałało to dla mnie. Jestem na JRE 1.6, Win 7. Twoje zdrowie!

szacunkiem,

@ Carpenter1010

3

Komenda new File właśnie tworzy instancję pliku przy użyciu danej nazwy ścieżki. W rzeczywistości nie tworzy pliku na dysku twardym.

Jeśli powiesz

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

To może wrócić prawdziwe tylko wtedy, gdy nie było istniejący plik o tej samej ścieżce. Jeśli chcesz sprawdzić ten sam plik zadeklarowany w pierwszym wierszu, być może będziesz musiał użyć go w ten sposób.

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

Teraz to się zwróci.

+0

małe wyjaśnienie: każde wywołanie konstruktora przy użyciu nowego słowa kluczowego tworzy Obiekt - tak samo jak w tym przypadku Obiekt opisany przez Klasę, której nazwa to Plik! więc nie instancja File! = descriptors :) – ceph3us

0

Oczywiście istnieje wiele możliwych przyczyn i poprzednie odpowiedzi udokumentować je dobrze, ale oto jak Rozwiązałem to w jednym konkretnym przypadku:

Student kopalni miał ten problem i mam prawie rozerwał moje włosy próbuje to rozgryźć. Okazało się, że plik nie istnieje, mimo że wyglądało na to. Problem polegał na tym, że system Windows 7 został skonfigurowany do "Ukrywania rozszerzeń plików znanych typów plików". Oznacza to, że jeśli plik ma nazwę "data.txt", jego faktyczna nazwa to "data.txt.txt".

Mam nadzieję, że to pomoże innym uratować sobie włosy.

+0

Nie sądzę, że to był problem w moim przypadku.Jak wspomniano w moim pytaniu: "Mogę skopiować i wkleić pełną ścieżkę do okna" Uruchom "w Windows, a plik otwiera się dobrze.", Co oznacza, że ​​plik faktycznie istnieje. – atsjoo

-1

myślę, że należy użyć backslash zamiast, jak to:

plik file = new File ("C: \\ użytkownik \\ Użytkowe \\ \\ someTextFile.txt Danych"); (dwa ukośniki nie literówka)

powinno rozwiązać problem :)

+1

Myślę, że problem jest bardziej związany ze ścieżką bezwzględną względem ścieżki względnej. Ukośnik jest poprawny w Javie nawet dla ścieżek Windows. –

0

Jeśli nie chcą zajmować się getAbsoluteFile() wywołuje za każdym razem trzeba wywołać metodę, lepiej utworzyć plik instancja już z absolutną ścieżką.To powinno załatwić:

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

Proponuję otoczyć go blokiem try-catch, BTW.

Powiązane problemy