Java: ścieżka vs plik

200

Czy w przypadku nowych aplikacji napisanych w Javie 7 istnieje jakikolwiek powód do używania java.io.Fileobiektu, czy możemy uznać go za przestarzały?

Wierzę, że java.nio.file.Pathmożna zrobić wszystko, co java.io.Filemożna zrobić i więcej.

dogbane
źródło

Odpowiedzi:

152

Krótko mówiąc:

java.io.Filenajprawdopodobniej nigdy nie będzie przestarzałe / nieobsługiwane. To powiedziawszy, java.nio.file.Pathjest częścią bardziej nowoczesnego java.nio.filelib i robi wszystko java.io.File, ale ogólnie lepiej i wiele więcej.

W przypadku nowych projektów użyj Path.

A jeśli kiedykolwiek potrzebujesz Fileobiektu dla starszej wersji, po prostu wywołaj Path # toFile ()

Migracja z pliku do ścieżki

Ta strona Oracle pasemka różnice i mapy java.io.File functionalitydojava.nio.file lib (including Path) functionality

Artykuł Janice J. Heiss i Sharon Zakhour, maj 2009, omawiający system plików NIO.2 w JDK 7

Don Cheadle
źródło
12
Możesz przeczytać komentarze Oracle dotyczące różnic tutaj: docs.oracle.com/javase/tutorial/essential/io/legacy.html
Josiah Yoder
4
Zauważ też, że „Pliki” (w liczbie mnogiej) nie są przestarzałe. Zasadniczo jest to klasa abstrakcyjna, która działa na obiektach Path i wykonuje wiele funkcji starej klasy File, takich jak isDirectory () lub exist ()
Josiah Yoder
2
Teraz zastanawiam się: dlaczego nowe okna dialogowe File / FolderChooser w JavaFX 8 nadal używają Filezamiast Path?
piegames,
2
Ścieżka to interfejs. Aby utworzyć instancję, użyj Paths.get (nazwa pliku). Może to wynikać z zamieszania związanego z koniecznością pisania Files.exists (Paths.get (nazwa pliku)) zamiast nowego pliku (nazwa pliku) .exists (), że starszy interfejs API jest nadal używany.
Josiah Yoder
Pathmożna łatwiej modyfikować, aby „dodawać dzieci” za pomocą resolve(...)lub „przechodzić o jeden poziom wyżej” za pomocą getParent()itp., podczas gdy Filenie można. Zasadniczo po zakończeniu modyfikacji Ścieżki często ją przekonwertujesz, toFile()aby można ją było wysłać na starsze metody, takie jak FileInputStreamkonstruktor.
MasterHD
18

czy możemy uznać to za przestarzałe?

Nie, nie możesz uważać go za przestarzały, dopóki nie zostanie zaznaczony w FileJavadoc.

Markiz Lorne
źródło
14
Nawet jeśli jest to jeden z tych „Ponieważ RFC tak mówi” - Odpowiedzi, nie uznałbym tego za dobrą odpowiedź. Oczywistym jest, że plik zostanie zastąpiony ścieżką. Jeśli chcesz wyprzedzić czas, możesz od razu zacząć korzystać ze ścieżki i użyć funkcji toFile () w razie potrzeby.
Chris
15
@Chris Nic nie zostało nigdy usunięte z JDK, ponieważ zmienili model zdarzeń AWT w wersji 1.02. To wcale nie jest „oczywiste”. To jest źle.
Markiz Lorne
5
@downvoters Ta odpowiedź jest zasadniczo tautologią. To nie może być źle. Uwaga: W ciągu pięciu lat, które upłynęły od napisania tej odpowiedzi, Java 8 pojawiła się później i java.io.Filenadal nie jest ani usuwana, ani przestarzała, a Javadoc nie zawiera niczego, co sugerowałoby, że któraś z tych rzeczy się wydarzy.
Markiz Lorne
2
@EJP Właśnie wziąłem pod uwagę twój komentarz. Nie jestem jednak do końca pewien, czy masz rację, gdy mówisz, że odpowiedź to tautologia. Pytanie, które prawdopodobnie należałoby uciszyć za to, że jest „oparte na opiniach”, brzmi „czy możemy uznać to za przestarzałe”. No tak, OP i ktokolwiek inny może , ale tak nie jest.
Mike gryzoni
@mikerodent Sugeruję, że to tylko świadome błędne odczytanie, o co tak naprawdę chodzi w tym pytaniu. Również częściowa wycena.
Markiz Lorne
8

Sprawdź ten artykuł, aby uzyskać więcej informacji - http://www.oracle.com/technetwork/articles/javase/nio-139333.html

Zasadniczo file.Path będzie odtąd drogą, ale jak powszechnie wiadomo, ludzie Java mają tendencję do zachowania kompatybilności wstecznej, więc sądzę, że właśnie dlatego ją zostawili.

LordDoskias
źródło
Czy zaktualizowałbyś link? Chciałbym przeczytać ten artykuł.
John B
Niestety nie mogłem znaleźć oryginalnego artykułu na stronie internetowej wyroczni. Oto wersja z maszyny powrotnej
LordDoskias
1
Znalazłem ten artykuł na normalnej stronie Oracle - dodano link do odpowiedzi.
Duncan Jones,
5

Wypełnię bardzo dobrą odpowiedź @mmcrae.

czy istnieje jakikolwiek powód do używania obiektu java.io.File, czy możemy uznać go za przestarzały?

Klasy JDK są bardzo rzadko przestarzałe.
Możesz zobaczyć na liście przestarzałych JDK 8 API wszystkie klasy przestarzałe od pierwszego JDK.
Zawiera tylko niewielką część klas, których odradza dokumentacja Oracle i społeczność Java.
java.util.Date, java.util.Vector, java.util.Hashtable... że są zajęcia z tak wielu wad nie są przestarzałe.
Ale dlaczego ?
Ponieważ koncepcyjnie coś deprecatedtam oznacza, ale zniechęca do używania, ponieważ z pewnością zostanie usunięty.
Tysiące programów polegają na tych źle zaprojektowanych klasach.
W przypadku takich klas programiści Java API nie dadzą takiego sygnału.

Odpowiedź @EJPjest naprawdę słuszna:

Nie, chyba że i dopóki nie zostanie tak zaznaczony w Javadoc.

Tak, myślę, że pytanie to więcej sensu w jego słowach:
„Jak mamy wyboru, musimy użyć java.io.Filealbo java.nio.file.Pathdo nowych sytuacji i jeśli odpowiedź brzmi java.nio.file.Path, można łatwo wykorzystać java.io.Filedo projektów przy użyciu starszych java.io.File?”

Wierzę, że plik java.nio.ath.ath może zrobić wszystko, co plik java.io.File i więcej.

Masz odpowiedź.

Ten samouczek wyroczni na temat starszych IO potwierdza twoje myślenie.

Przed wydaniem Java SE 7 java.io.Fileklasa była mechanizmem używanym do operacji we / wy pliku, ale miała kilka wad.

Wiele metod nie zgłaszało wyjątków, gdy zawiodły, dlatego niemożliwe było uzyskanie użytecznego komunikatu o błędzie. Na przykład, jeśli usunięcie pliku nie powiedzie się, program otrzyma komunikat „niepowodzenie usunięcia”, ale nie będzie wiedział, czy to dlatego, że plik nie istnieje, użytkownik nie miał uprawnień lub wystąpił inny problem.

Metoda zmiany nazwy nie działała konsekwentnie na różnych platformach. Nie było rzeczywistego wsparcia dla dowiązań symbolicznych.

Potrzebna była większa obsługa metadanych, takich jak uprawnienia do pliku, właściciel pliku i inne atrybuty bezpieczeństwa.

Dostęp do metadanych pliku był nieefektywny.

Wiele metod File nie skalowało się. Żądanie dużej listy katalogów przez serwer może spowodować zawieszenie się. Duże katalogi mogą również powodować problemy z zasobami pamięci, powodując odmowę usługi.

Nie było możliwe napisanie wiarygodnego kodu, który mógłby rekurencyjnie chodzić po drzewie plików i odpowiednio reagować, jeśli były okrągłe dowiązania symboliczne.

Przy tak wielu wadach java.io.File, tak naprawdę nie potrzebujemy powodu, aby używać tej klasy do nowych prac.
Nawet w przypadku użycia starszego kodu java.io.FileOracle daje wskazówki do użycia Path.

Być może masz starszy kod, który używa java.io.File i chciałbyś skorzystać z funkcjonalności java.nio.file.Path przy minimalnym wpływie na Twój kod.

Klasa java.io.File udostępnia metodę toPath, która konwertuje instancję File w starym stylu na instancję java.nio.file.Path w następujący sposób:

Path input = file.toPath();

Następnie możesz skorzystać z bogatego zestawu funkcji dostępnych dla klasy Path.

Załóżmy na przykład, że masz kod, który usunął plik:

file.delete();

Możesz zmodyfikować ten kod, aby użyć metody Files.delete w następujący sposób:

Path fp = file.toPath();
Files.delete(fp);
davidxxx
źródło
Krótko mówiąc, on / ona może rzeczywiście uznać to za przestarzałe, jeśli chce.
Mike gryzoń
@mike gryzoni. Dokładnie. Z koncepcyjnego punktu widzenia powinna ona / on, chociaż nie jest tak w przypadku Javadoc z wyjaśnionych powodów.
davidxxx
4

Tak, ale wiele istniejących interfejsów API, w tym standardowe interfejsy API Java7, nadal działa tylko z Filetypem.

niezaprzeczalny
źródło
8
Obiekty ścieżki można przekonwertować na obiekty File za pomocą Path.toFile () , a następnie użyć standardowych interfejsów API.
jacktrades
2
Więc twoja odpowiedź brzmi „tak, ale nie”?
Markiz Lorne
1

Plik Java.io.File nie jest przestarzały. Tak, java.nio.file.Path jest lepszy, ale dopóki jest mnóstwo programów i podręczników korzystających z Java.io.File, choćby ze względów starszych, nie należy go uważać za przestarzały, jest zbyt ważny. Takie postępowanie byłoby po prostu rzuceniem klucza w dzieło bez żadnego zysku. Na przykład struktura systemu Android używa pliku do niektórych podstawowych funkcji obsługi plików, wiele innych rzeczy robi.

Andrew S.
źródło
Nie zapytał, czy Pathjest lepiej. Zapytał, czy Filejest przestarzały.
Markiz Lorne
1
@EJP Myślę, że jesteś trochę przesadny. OP zapytał, czy plik java.io.File jest przestarzały, a ja odpowiedziałem na to. Stwierdził także: „Wierzę, że plik java.nio.ath.ath może zrobić wszystko, co plik java.io.File i więcej.” Ja tylko potwierdzałem jego komentarz, nie warto było głosować w dół.
Andrew S
-9

Czy w przypadku nowych aplikacji napisanych w Javie 7 istnieje jakiś powód do używania obiektu java.io.File, czy możemy uznać go za przestarzały?

To trochę jak powiedzenie: „czy Napoleon powinien najechać Rosję, czy te brukselki naprawdę są smaczne?”

Co do drugiej części pytania, można rzeczywiście uznać je za przestarzałe. Od stycznia 2018 r. Nie jest przestarzałe. Ale nic nie stoi na przeszkodzie, abyś to rozważył . Nie da się powiedzieć, czy zapewni ci to jakąś przewagę w tym życiu, czy w następnym.

gryzoń mike
źródło
5
Nie rozumiem twojej analogii.
Tunaki,
Każde pytanie „lub” powinno przedstawiać dwie logiczne alternatywy, z których każda zasadniczo odpowiada na to samo pytanie.
Mike gryzoni
Niestety, w tym kontekście brzmi to bardzo pedantycznie. Pomysł brzmi: „Chcę użyć File. Czy powinienem, tak czy nie?”
Tunaki,
1
Tak, zgadzam się, że jest to załadowane pytanie ... zwłaszcza, że ​​i tak wiele istniejących interfejsów API innych firm nadal używa File. W najbliższym czasie nie umrze.
Tunaki,
3
it isn't deprecated. But there's nothing to stop you *considering* it soLOL.
Don Cheadle