2012-07-20 23 views
11

Moja aplikacja Java (która jest dość fragmentem kodu) wykonuje wiele operacji na plikach. W pewnym momencie mojej aplikacji muszę przenieść plik z jednej lokalizacji do drugiej i do tego używam metody Files.move z JDK7.Wymuś java, aby zwolnić wszystkie blokady plików/uchwyty w Javie

Kiedy próbuję to zrobić, pojawia się błąd informujący mnie, że plik jest w użyciu. Wiem na pewno, że to część mojego kodu blokuje ten zasób.

Jak wymusić na mojej aplikacji Java zwolnienie wszystkich blokad przed wywołaniem funkcji, która przenosi/zmienia nazwę mojego pliku?

Jeśli nie jest to możliwe, czy istnieje łatwy sposób sprawdzenia, która część mojego kodu blokuje plik? Przechodzenie przez cały mój kod w poszukiwaniu niezamkniętych uchwytów plików byłoby koszmarem, biorąc pod uwagę ilość kodu.

Dzięki

+0

może pomóc: http://stackoverflow.com/questions/4179145/release-java-file-lock-in-windows – Chris

Odpowiedz

3

Z pomocą debuggera można zobaczyć wszystkie instancje obiektów, które masz w pamięci (w Netbeans będzie to system Windows | Debugging | Załadowane klas, a następnie kliknij prawym przyciskiem myszy -> Pokaż przypadki). Następnie możesz zobaczyć wszystkie instancje, które posiadasz, i wskazać te, które wskazują na plik, który próbujesz przenieść. Po znalezieniu odniesienia do pliku możesz zobaczyć, kto nadal go zawiera.

Jeśli nikt nie ma odniesienia do pliku, być może instancja została odrzucona bez wywoływania close(), a plik byłby normalnie zwalniany tylko po zbiorze śmieci. To sprawia, że ​​poprzednie podejście jest bezużyteczne, ponieważ uważam, że debugger automatycznie wyrzuciłby te strumienie za Ciebie. Być może mógłbyś umieścić warunkowy punkt przerwania w konstruktorze strumienia i nakazać mu zatrzymanie się tylko wtedy, gdy parametr konstruktora odnosi się do twojego pliku.

Jeśli nie możesz znaleźć niczego, w ostateczności możesz spróbować wykonać kilka połączeń System.gc() przed operacją przenoszenia i sprawdzić, czy masz jakąś poprawę. Oczywiście byłoby to tylko szybkie i brudne rozwiązanie, aby dać ci trochę czasu, aż znajdziesz rzeczywisty problem.

+0

W rzeczywistości instancje 'File' nie przechowują blokad plików. "Plik" to tylko reprezentacja nazwy pliku lub ścieżki do katalogu. 'System.gc()' nigdy nie zamyka żadnych otwartych strumieni plików. –

+0

Masz rację co do 'Plik'. Poprawiłem odpowiedź, aby odnieść się do 'FileInputStream' /' FileOutputStream'. Utrzymuję jednak moją radę na temat 'System.gc()': dwie klasy mają metodę 'finalize', która zamyka strumień, więc jeśli po prostu odrzuciłeś obiekt bez wywoływania close, może pomóc zbieranie śmieci. – Flavio

+0

Masz rację odnośnie finalizowania() w strumieniach plików, więc masz rację, może to pomóc. To jest łuszcząca się! Nie można kontrolować, kiedy odbywa się proces zbierania śmieci, ani tego, co jest gromadzone, więc nie należy polegać na takich zachowaniach w procesie produkcyjnym. –

3

Każde rozwiązanie inne niż zamknięcie linii prawidłowo (najlepiej w ramach bloku try.. finally) będzie zadaniem bum i może spowodować, że rzeczy staną się bardziej niestabilne niż są już.

Wiem, że trudno to naprawić w dużej bazie kodu. Jeśli nie chcesz brnąć przez kod, FindBugs dobrze odnajduje zamknięte strumienie. Istnieje wtyczka Eclipse i możesz filtrować znalezione błędy tylko dla tych, które Cię interesują.

3

Obiekt File() nie blokuje pliku, ale obiekt FileStream (FileInputStream/FileOutputStream) blokuje go. Więc musisz napisać HelperClass (np. Singleton) dla swoich strumieni, które rejestrują wszystkie strumienie.

Ale zauważ, że jeśli masz wyciek z kodu, lepiej jest naprawić błąd niż zamknąć wszystkie trudne pliki.

Powiązane problemy