Java: Đường dẫn vs Tệp


200

Đối với các ứng dụng mới được viết bằng Java 7, có lý do nào để sử dụng một java.io.Fileđối tượng nữa không hoặc chúng ta có thể xem xét nó không dùng nữa không?

Tôi tin rằng a java.nio.file.Pathcó thể làm mọi thứ a java.io.Filecó thể làm và hơn thế nữa.

Câu trả lời:


153

Mẩu chuyện dài:

java.io.Filerất có thể sẽ không bao giờ bị phản đối / không được hỗ trợ. Điều đó nói rằng, java.nio.file.Pathlà một phần của java.nio.filelib hiện đại hơn , và làm mọi thứ java.io.Filecó thể, nhưng nói chung là theo cách tốt hơn, và nhiều hơn nữa.

Đối với các dự án mới, sử dụng Path.

Và nếu bạn cần một Fileđối tượng để kế thừa, chỉ cần gọi Đường dẫn # toFile ()

Di chuyển từ tệp sang đường dẫn

Trang Oracle này nêu bật sự khác biệt và ánh xạ java.io.File functionalitytớijava.nio.file lib (including Path) functionality

Bài viết của Janice J. Heiss và Sharon Zakhour, tháng 5 năm 2009, thảo luận về Hệ thống tệp NIO.2 trong JDK 7


12
Bạn có thể đọc ý kiến ​​của Oracle về sự khác biệt ở đây: docs.oracle.com/javase/tutorial/essential/io/legacy.html
Josiah Yoder

4
Cũng lưu ý rằng "Tệp" (ở số nhiều) không được dùng nữa. Nó thực chất là một lớp trừu tượng hoạt động trên các đối tượng Path và thực hiện nhiều tính năng của lớp File cũ, chẳng hạn như isDirectory () hoặc tồn tại ()
Josiah Yoder

2
Bây giờ tôi đang tự hỏi: tại sao các hộp thoại File / FolderChooser mới trong JavaFX 8 sau đó vẫn sử dụng Filethay vì Path?
piegames

2
Đường dẫn là một giao diện. Để tạo một thể hiện, sử dụng Paths.get (tên tệp). Có thể do nhầm lẫn khi phải viết Files.exists (Paths.get (tên tệp)) thay vì Tệp mới (tên tệp) .exists () mà API cũ vẫn được sử dụng.
Josiah Yoder

Pathcó thể dễ dàng sửa đổi hơn để "thêm trẻ em" với resolve(...)hoặc "di chuyển lên một cấp" với getParent(), v.v. trong khi Filekhông thể. Về cơ bản một khi bạn đã hoàn thành sửa đổi Đường dẫn, bạn sẽ thường chuyển đổi nó toFile()để có thể gửi nó thành các phương thức cũ, chẳng hạn như hàm FileInputStreamtạo.
MasterHD

18

chúng ta có thể xem xét nó không dùng nữa?

Không, bạn không thể xem xét nó không được chấp nhận trừ khi và cho đến khi nó được đánh dấu trong FileJavadoc.


14
Ngay cả khi đây là một trong những câu "Bởi vì RFC nói như vậy" -Nhận xét, tôi sẽ không coi đó là một câu trả lời hay. Rõ ràng là File sẽ được thay thế bởi Path. Nếu bạn muốn đi trước thời đại, bạn có thể bắt đầu sử dụng Đường dẫn ngay lập tức và sử dụng toFile () khi cần thiết.
Chris

15
@Chris Không có gì đã bị xóa khỏi JDK kể từ khi họ thay đổi mô hình sự kiện AWT trong 1.02. Nó hoàn toàn không "rõ ràng". Nó sai.
Hầu tước Lorne

5
@downvoters Câu trả lời này thực chất là một tautology. Nó không thể sai được. NB Trong năm năm kể từ khi tôi viết câu trả lời này, Java 8 sau đó đã xuất hiện và java.io.Filevẫn không bị loại bỏ hay thậm chí không được phản đối, và vẫn không có gì trong Javadoc cho rằng một trong những điều này sẽ xảy ra.
Hầu tước Lorne

2
@EJP Tôi vừa nêu lên nhận xét đó của bạn. Tuy nhiên, tôi không hoàn toàn chắc chắn rằng bạn đúng khi bạn nói câu trả lời là một tautology. Câu hỏi, có lẽ đã bị đè bẹp vì "dựa trên quan điểm", là "chúng ta có thể coi đó là phản đối không". Vâng, vâng, OP và bất cứ ai khác có thể , nhưng không phải vậy.
mike gặm nhấm

@mikerodent Tôi đề nghị đó chỉ là một sự cố tình đọc sai về những gì câu hỏi thực sự là về. Cũng là một trích dẫn một phần.
Hầu tước Lorne

8

Kiểm tra bài viết này về thông tin thêm - http://www.oracle.com/technetwork/articles/javase/nio-139333.html

Về cơ bản file.Path sẽ là cách để đi từ bây giờ nhưng như Java được biết đến rộng rãi, mọi người có xu hướng giữ tính tương thích trở lại vì vậy tôi đoán đó là lý do tại sao họ đã rời bỏ nó.


Bạn vui lòng cập nhật liên kết? Tôi muốn đọc bài viết này.
John B

Thật không may, tôi không thể tìm thấy bài viết gốc trên trang web oracle. Đây là một phiên bản từ máy Wayback: web.archive.org/web/20090601091119/http://java.sun.com/...
LordDoskias

1
Tôi tìm thấy bài viết một lần nữa về phía Oracle bình thường - liên kết được thêm vào để trả lời.
Duncan Jones

5

Tôi sẽ hoàn thành câu trả lời rất tốt của @mmcrae.

Có bất kỳ lý do để sử dụng một đối tượng java.io.File nữa hay chúng ta có thể xem xét nó không dùng nữa?

Các lớp JDK rất hiếm khi bị phản đối.
Bạn có thể thấy trên API JDK 8 không dùng nữa liệt kê tất cả các lớp không dùng nữa kể từ JDK đầu tiên.
Nó chỉ chứa một phần nhỏ các lớp mà tài liệu Oracle và cộng đồng Java không khuyến khích sử dụng.
java.util.Date, java.util.Vector, java.util.Hashtable... đó là lớp học với rất nhiều khiếm khuyết không phản đối.
Nhưng tại sao ?
Bởi vì về mặt khái niệm một cái gì đó deprecatedcó nghĩa là vẫn còn nhưng không khuyến khích sử dụng vì nó chắc chắn sẽ bị loại bỏ.
Hàng ngàn chương trình dựa vào các lớp được thiết kế xấu này.
Đối với các lớp như vậy, các nhà phát triển API Java sẽ không đưa ra tín hiệu như vậy.

Câu trả lời @EJPlà rất đúng:

Không trừ khi và cho đến khi nó được đánh dấu như vậy trong Javadoc.

Vì vậy, tôi nghĩ rằng câu hỏi của bạn sẽ có ý nghĩa hơn trong các điều khoản của nó:
"Khi chúng ta có sự lựa chọn, chúng ta nên sử dụng java.io.Filehoặc java.nio.file.Pathcho các phát triển mới và nếu câu trả lời là java.nio.file.Path, bạn có thể dễ dàng tận dụng java.io.Filecác dự án cũ java.io.Filekhông?"

Tôi tin rằng một java.nio.file.Path có thể làm mọi thứ mà java.io.File có thể làm và hơn thế nữa.

Bạn có câu trả lời.

Hướng dẫn tiên tri này về di sản IO xác nhận suy nghĩ của bạn.

Trước khi phát hành Java SE 7, java.io.Filelớp là cơ chế được sử dụng cho tệp I / O, nhưng nó có một số nhược điểm.

Nhiều phương pháp đã không đưa ra ngoại lệ khi chúng thất bại, vì vậy không thể có được thông báo lỗi hữu ích. Ví dụ: nếu xóa tệp không thành công, chương trình sẽ nhận được "xóa thất bại" nhưng sẽ không biết có phải do tệp không tồn tại hay không, người dùng không có quyền hoặc có một số vấn đề khác.

Phương thức đổi tên không hoạt động nhất quán trên các nền tảng. Không có hỗ trợ thực sự cho các liên kết tượng trưng.

Cần hỗ trợ thêm cho siêu dữ liệu, như quyền tệp, chủ sở hữu tệp và các thuộc tính bảo mật khác.

Truy cập siêu dữ liệu tập tin là không hiệu quả.

Nhiều phương thức File không mở rộng được. Yêu cầu một danh sách thư mục lớn trên một máy chủ có thể dẫn đến treo. Các thư mục lớn cũng có thể gây ra sự cố tài nguyên bộ nhớ, dẫn đến việc từ chối dịch vụ.

Không thể viết mã đáng tin cậy có thể đệ quy một cây tập tin và trả lời thích hợp nếu có các liên kết tượng trưng tròn.

Với rất nhiều nhược điểm java.io.File, chúng tôi thực sự không cần lý do để sử dụng lớp này cho các phát triển mới.
Và ngay cả đối với mã kế thừa sử dụng java.io.File, Oracle đưa ra gợi ý để sử dụng Path.

Có lẽ bạn có mã kế thừa sử dụng java.io.File và muốn tận dụng chức năng java.nio.file.Path với tác động tối thiểu đến mã của bạn.

Lớp java.io.File cung cấp phương thức toPath, nó chuyển đổi một thể hiện tệp kiểu cũ thành một thể hiện java.nio.file.Path, như sau:

Path input = file.toPath();

Sau đó, bạn có thể tận dụng bộ tính năng phong phú có sẵn cho lớp Đường dẫn.

Ví dụ: giả sử bạn có một số mã đã xóa một tệp:

file.delete();

Bạn có thể sửa đổi mã này để sử dụng phương thức Files.delete, như sau:

Path fp = file.toPath();
Files.delete(fp);

Nói tóm lại, cô ấy / anh ấy thực sự có thể coi đó sự phản đối nếu cô ấy / anh ấy muốn.
mike gặm nhấm

@mike gặm nhấm. Chính xác. Về mặt khái niệm cô ấy / anh ấy nên trong khi đó không phải là trường hợp của Javadoc vì lý do được giải thích.
davidxxx

4

Có, nhưng nhiều API hiện có, bao gồm các API tiêu chuẩn của riêng Java7, vẫn chỉ hoạt động với Fileloại.


8
Các đối tượng đường dẫn có thể được chuyển đổi thành các đối tượng Tệp bằng Path.toFile () , sau đó sử dụng các API tiêu chuẩn.
jacktrades

2
Vì vậy, câu trả lời của bạn là "có nhưng không"?
Hầu tước Lorne

1

Java.io.File không được dùng nữa. Có java.nio.file.Path tốt hơn, nhưng miễn là vẫn còn nhiều chương trình và sách văn bản sử dụng Java.io.File, nếu chỉ vì lý do di sản, nó không nên bị coi là phản đối, nó quá quan trọng. Làm như vậy sẽ chỉ là ném một cờ lê trong công việc mà không vượt quá tất cả. Ví dụ, khung Android sử dụng Tệp cho một số tính năng xử lý tệp cơ bản của nó, nhiều việc khác phải làm.


Anh không hỏi liệu có Pathtốt hơn không. Anh hỏi có Filebị phản đối không.
Hầu tước Lorne

1
@EJP Tôi nghĩ bạn đang hơi quá lời. OP đã hỏi liệu java.io.File có bị phản đối không và tôi đã trả lời rằng .. Ông cũng tuyên bố "Tôi tin rằng java.nio.file.Path có thể làm mọi thứ mà java.io.File có thể làm và hơn thế nữa." Tôi chỉ đơn thuần xác nhận bình luận của anh ấy, nó hầu như không đáng để bỏ phiếu.
Andrew S

-9

Đối với các ứng dụng mới được viết bằng Java 7, có lý do nào để sử dụng đối tượng java.io.File nữa hay chúng ta có thể xem xét nó không dùng nữa không?

Điều này hơi giống như nói: "Napoleon nên xâm chiếm Nga, hay những mầm Brussels này thực sự ngon?"

Đối với phần thứ hai của câu hỏi, bạn thực sự có thể xem xét nó không được chấp nhận. Kể từ tháng 1 năm 2018, nó không bị phản đối. Nhưng không có gì ngăn cản bạn xem xét nó như vậy. Cho dù điều đó sẽ mua cho bạn bất kỳ lợi thế trong cuộc sống này hoặc tiếp theo là không thể nói.


5
Tôi không hiểu sự tương tự của bạn.
Tunaki

Bất kỳ câu hỏi "hoặc" nào cũng nên trình bày hai phương án hợp lý, cả hai câu hỏi này đều trả lời cùng một câu hỏi.
mike gặm nhấm

Xin lỗi, điều này nghe có vẻ rất phạm vi trong bối cảnh này. Ý tưởng là "Tôi muốn sử dụng File. Tôi nên, có hay không?"
Tunaki

1
Vâng, tôi đồng ý rằng đó là một câu hỏi được tải ... đặc biệt là vì rất nhiều API của bên thứ 3 hiện tại vẫn sử dụng File. Nó sẽ không chết bất cứ lúc nào sớm.
Tunaki

3
it isn't deprecated. But there's nothing to stop you *considering* it soCƯỜI LỚN.
Don Cheadle
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.