Java: ไฟล์พา ธ vs


200

สำหรับแอปพลิเคชันใหม่ที่เขียนใน Java 7 มีเหตุผลใดที่จะใช้java.io.Fileวัตถุอีกต่อไปหรือเราจะพิจารณาว่าเลิกใช้แล้วหรือไม่?

ฉันเชื่อว่าjava.nio.file.Pathทุกสิ่งjava.io.Fileสามารถทำได้และทำได้มากกว่านี้

คำตอบ:


152

เรื่องสั้นสั้น:

java.io.Fileส่วนใหญ่จะไม่ถูกปฏิเสธ / ไม่ได้รับการสนับสนุน ที่กล่าวว่าjava.nio.file.Pathเป็นส่วนหนึ่งของjava.nio.filelib ทันสมัยมากขึ้นและทำทุกอย่างได้java.io.Fileแต่โดยทั่วไปในทางที่ดีขึ้นและมากขึ้น

Pathสำหรับโครงการใหม่ใช้

และถ้าคุณต้องการFileวัตถุสำหรับมรดกเพียงแค่เรียกPath # toFile ()

การโอนย้ายจากไฟล์ไปยังพา ธ

หน้า Oracle นี้เน้นความแตกต่างและแผนที่java.io.File functionalityไปjava.nio.file lib (including Path) functionality

บทความโดย Janice J. Heiss และ Sharon Zakhour พฤษภาคม 2009 หารือเกี่ยวกับระบบไฟล์ NIO.2 ใน JDK 7


12
คุณสามารถอ่านความคิดเห็นของ Oracle เกี่ยวกับความแตกต่างได้ที่นี่: docs.oracle.com/javase/tutorial/essential/io/legacy.html
Josiah Yoder

4
โปรดทราบด้วยว่า "ไฟล์" (ในพหูพจน์) ไม่ได้ถูกคัดค้าน มันเป็นคลาสนามธรรมที่ทำงานบนวัตถุ Path และดำเนินการคุณสมบัติหลายอย่างของคลาสไฟล์เก่าเช่น isDirectory () หรือมีอยู่ ()
Josiah Yoder

2
ตอนนี้ฉันสงสัยว่าทำไมทำใหม่กล่องโต้ตอบไฟล์ / FolderChooser ใน JavaFX 8 แล้วยังคงใช้FileแทนPath?
piegames

2
Path เป็นส่วนต่อประสาน หากต้องการสร้างอินสแตนซ์ให้ใช้ Paths.get (ชื่อไฟล์) อาจเป็นเพราะความสับสนในการเขียน Files.exists (Paths.get (ชื่อไฟล์)) แทนไฟล์ใหม่ (filename) .exists () ที่ API เก่ายังคงใช้อยู่
Josiah Yoder

Pathสามารถแก้ไขได้ง่ายขึ้นเพื่อ "เพิ่มลูก" ด้วยresolve(...)หรือ "เลื่อนระดับหนึ่ง" ด้วยgetParent()ฯลฯ โดยที่Fileไม่สามารถทำได้ เป็นหลักเมื่อคุณปรับเปลี่ยน Path เสร็จแล้วคุณจะแปลงมันบ่อยครั้งtoFile()เพื่อให้สามารถส่งเป็นวิธีดั้งเดิมเช่นFileInputStreamConstructor ได้
MasterHD

18

เราจะพิจารณาว่าเลิกใช้แล้วได้หรือไม่

ไม่คุณไม่สามารถพิจารณาว่าจะเลิกใช้จนกว่าจะมีการทำเครื่องหมายในFileJavadoc


14
แม้ว่านี่จะเป็นหนึ่งใน "เพราะ RFC พูดว่า" คำตอบ - ฉันจะไม่ถือว่าเป็นคำตอบที่ดี เห็นได้ชัดว่า File จะถูกแทนที่ด้วย Path ถ้าคุณต้องการที่จะล่วงหน้าคุณสามารถเริ่มใช้ Path ทันทีและใช้ toFile () เมื่อจำเป็น
Chris

15
@Chris ไม่มีอะไรถูกลบออกจาก JDK เนื่องจากพวกเขาเปลี่ยนรูปแบบเหตุการณ์ AWT ใน 1.02 มันไม่ได้ 'ชัดเจน' เลย มันผิด.
มาร์ควิสแห่ง Lorne

5
@downvoters คำตอบนี้เป็นหลักซ้ำซาก มันไม่ผิดหรอก NB ในห้าปีนับตั้งแต่ฉันเขียนคำตอบนี้ Java 8 ได้ปรากฏตัวขึ้นในภายหลังและjava.io.Fileยังไม่ถูกลบออกหรือเลิกใช้แล้วและยังไม่มีอะไรใน Javadoc ที่จะแนะนำว่าสิ่งเหล่านี้จะเกิดขึ้นอย่างใดอย่างหนึ่ง
มาร์ควิสแห่ง Lorne

2
@EJP ฉันเพิ่งลบความคิดเห็นของคุณ อย่างไรก็ตามฉันไม่แน่ใจว่าคุณพูดถูกหรือไม่ คำถามที่น่าจะถูกแบนเพราะ "อิงตามความคิดเห็น" คือ "เราจะพิจารณาได้ไหมว่าเลิกใช้แล้ว" ใช่แล้ว OP และทุกคนสามารถทำได้แต่มันก็ไม่ได้
ไมค์หนู

@ Mikerodent ฉันแนะนำว่าเป็นเพียงการจงใจอ่านผิดในสิ่งที่เป็นคำถามเกี่ยวกับ ยังเป็นคำพูดบางส่วน
มาร์ควิสแห่ง Lorne

8

ตรวจสอบบทความนี้เกี่ยวกับข้อมูลเพิ่มเติม - http://www.oracle.com/technetwork/articles/javase/nio-139333.html

โดยพื้นฐานแล้วไฟล์แพทจะเป็นวิธีที่จะดำเนินการต่อจากนี้ไป แต่ในฐานะที่เป็นที่รู้กันดีว่าคน Java มักจะใช้งานร่วมกันได้ดังนั้นฉันคิดว่านั่นเป็นสาเหตุที่พวกเขาทิ้งมันไว้


คุณช่วยอัพเดทลิงค์ได้ไหม ฉันต้องการอ่านบทความนี้
John B

น่าเสียดายที่ฉันไม่พบบทความต้นฉบับในหน้าเว็บ oracle นี่คือรุ่นจากเครื่อง wayback: web.archive.org/web/20090601091119/http://java.sun.com/…
LordDoskias

1
ฉันพบบทความอีกครั้งในด้านปกติของ Oracle - เพิ่มลิงค์เพื่อตอบ
ดันแคนโจนส์

5

@mmcraeฉันจะเสร็จสิ้นคำตอบที่ดีมากของ

มีเหตุผลใดที่จะใช้วัตถุ java.io.File อีกต่อไปหรือเราจะพิจารณาว่าเลิกใช้แล้วหรือไม่?

คลาส JDK เลิกใช้บ่อยมาก
คุณสามารถดูรายการเลิกใช้ JDK 8 APIทุกคลาสที่เลิกใช้ตั้งแต่ JDK แรก
มันมีเพียงส่วนน้อยของคลาสที่เอกสาร Oracle และชุมชน Java กีดกันที่จะใช้
java.util.Date, java.util.Vector, java.util.Hashtable... ที่มีชั้นเรียนที่มีข้อบกพร่องอื่น ๆ จำนวนมากไม่ได้เลิก
แต่ทำไม
เพราะแนวความคิดบางอย่างของdeprecatedวิธีการยังคงมี แต่ไม่แนะนำให้ใช้เพราะมันจะถูกลบอย่างแน่นอน
โปรแกรมหลายพันโปรแกรมพึ่งพาคลาสที่ออกแบบมาไม่ดีเหล่านี้
สำหรับคลาสดังกล่าวผู้พัฒนา Java API จะไม่ให้สัญญาณดังกล่าว

คำตอบ@EJPคือถูกต้องจริงๆ:

ไม่เว้นแต่และจนกว่าจะมีการทำเครื่องหมายใน Javadoc

ดังนั้นฉันคิดว่าคำถามของคุณจะมีเหตุผลมากกว่านี้:
"เมื่อเรามีทางเลือกเราควรใช้java.io.Fileหรือjava.nio.file.Pathเพื่อการพัฒนาใหม่และถ้าคำตอบคือjava.nio.file.Pathคุณจะสามารถใช้ประโยชน์จากjava.io.Fileโปรเจ็กต์รุ่นเก่าได้java.io.Fileหรือไม่"

ฉันเชื่อว่า java.nio.file.Path สามารถทำทุกอย่างที่ java.io.File สามารถทำได้และอีกมากมาย

คุณมีคำตอบ

ออราเคิลบทสอนเกี่ยวกับมรดก IO ยืนยันความคิดของคุณ

ก่อนหน้าการเปิดตัว Java SE 7 java.io.Fileคลาสเป็นกลไกที่ใช้สำหรับไฟล์ I / O แต่มีข้อเสียหลายประการ

วิธีการมากมายไม่ได้ส่งข้อยกเว้นเมื่อล้มเหลวดังนั้นจึงเป็นไปไม่ได้ที่จะได้รับข้อความแสดงข้อผิดพลาดที่เป็นประโยชน์ ตัวอย่างเช่นหากการลบไฟล์ล้มเหลวโปรแกรมจะได้รับ "การลบล้มเหลว" แต่ไม่ทราบว่าเป็นเพราะไฟล์ไม่มีอยู่หรือไม่ผู้ใช้ไม่มีสิทธิ์หรือมีปัญหาอื่น ๆ

วิธีการเปลี่ยนชื่อไม่ทำงานอย่างสม่ำเสมอในแพลตฟอร์มต่างๆ ไม่มีการสนับสนุนที่แท้จริงสำหรับลิงก์สัญลักษณ์

ต้องการการสนับสนุนเพิ่มเติมสำหรับข้อมูลเมตาเช่นสิทธิ์ของไฟล์เจ้าของไฟล์และคุณลักษณะความปลอดภัยอื่น ๆ

การเข้าถึงข้อมูลเมตาของไฟล์ไม่มีประสิทธิภาพ

วิธีการหลายไฟล์ไม่ได้ปรับขนาด การร้องขอรายชื่อไดเรกทอรีขนาดใหญ่บนเซิร์ฟเวอร์อาจทำให้แฮงค์ ไดเรกทอรีขนาดใหญ่อาจทำให้เกิดปัญหาทรัพยากรหน่วยความจำส่งผลให้การปฏิเสธบริการ

ไม่สามารถเขียนรหัสที่เชื่อถือได้ซึ่งสามารถเดินทรีไฟล์และตอบกลับอย่างเหมาะสมหากมีการเชื่อมโยงสัญลักษณ์แบบวงกลม

ด้วยข้อเสียมากมายjava.io.Fileเราไม่จำเป็นต้องใช้ชั้นเรียนนี้เพื่อการพัฒนาใหม่ ๆ
และแม้กระทั่งสำหรับรหัสเดิมใช้ออราเคิลช่วยให้คำแนะนำในการใช้งานjava.io.FilePath

บางทีคุณอาจมีรหัสดั้งเดิมที่ใช้ java.io.File และต้องการใช้ประโยชน์จากฟังก์ชัน java.nio.file.Path ที่มีผลกระทบต่อโค้ดน้อยที่สุด

คลาส java.io.File จัดเตรียมเมธอด toPath ซึ่งแปลงอินสแตนซ์ File แบบเก่าเป็นอินสแตนซ์ java.nio.file.Path ดังต่อไปนี้:

Path input = file.toPath();

จากนั้นคุณสามารถใช้ประโยชน์จากชุดคุณลักษณะที่มีให้กับคลาส Path

ตัวอย่างเช่นสมมติว่าคุณมีรหัสที่ลบไฟล์:

file.delete();

คุณสามารถแก้ไขโค้ดนี้เพื่อใช้เมธอด Files.delete ดังต่อไปนี้:

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

กล่าวโดยสังเขปเธอ / เขาสามารถพิจารณาได้อย่างแน่นอนว่าเขา / เธอต้องการ
ไมค์หนู

@ หนูไมค์ เผง โดยทั่วไปแล้วเธอควรจะคิดในขณะที่มันไม่ใช่ในแง่ของ Javadoc ด้วยเหตุผลที่อธิบาย
davidxxx

4

ใช่ แต่ API ที่มีอยู่จำนวนมากรวมถึง API มาตรฐานของ Java7 ยังคงใช้งานได้กับFileประเภทเท่านั้น


8
วัตถุเส้นทางสามารถแปลงเป็นวัตถุไฟล์โดยใช้Path.toFile ()จากนั้นใช้ API มาตรฐาน
jacktrades

2
ดังนั้นคำตอบของคุณคือ 'ใช่ แต่ไม่ใช่'?
มาร์ควิสแห่งลอร์น

1

Java.io.File ไม่ได้ถูกปฏิเสธ ใช่ java.nio.file.Path จะดีกว่า แต่ตราบใดที่ยังมีโปรแกรมและหนังสือตำราจำนวนมากที่ใช้ Java.io.File หากเพียงเพื่อเหตุผลดั้งเดิมเท่านั้นไม่ควรพิจารณาว่าเลิกใช้มันสำคัญเกินไป การทำเช่นนั้นเพียงแค่โยนประแจในงานเพื่อไม่ให้เกินกำไรทั้งหมด ตัวอย่างเช่นกรอบการทำงานของ Android ใช้ไฟล์สำหรับคุณสมบัติการจัดการไฟล์ขั้นพื้นฐานบางอย่างมีหลายสิ่งที่ต้องทำ


เขาไม่ได้ถามว่าPathดีกว่าหรือไม่ เขาถามว่าFileเลิกหรือไม่
มาร์ควิสแห่ง Lorne

1
@EJP ฉันคิดว่าคุณเป็นคนคล่องแคล่วเล็กน้อย OP ได้ถามว่า java.io.File เลิกใช้แล้วหรือไม่และฉันตอบว่า .. เขายังกล่าวอีกว่า "ฉันเชื่อว่า java.nio.file.Path สามารถทำทุกอย่างที่ java.io.File สามารถทำได้และอื่น ๆ อีกมากมาย" ฉันแค่ยืนยันความคิดเห็นของเขามันแทบจะไม่คุ้มค่ากับการลงคะแนน
Andrew S

-9

สำหรับแอปพลิเคชันใหม่ที่เขียนใน Java 7 มีเหตุผลใดที่จะใช้ java.io.File object อีกต่อไปหรือเราจะพิจารณาว่าเลิกใช้แล้วหรือไม่?

นี่เป็นคำที่พูดว่า: "นโปเลียนควรบุกรัสเซียหรือถั่วงอกบรัสเซลส์เหล่านี้อร่อยจริงเหรอ"

ในส่วนที่สองของคำถามคุณสามารถพิจารณาได้อย่างแน่นอนว่าเลิกใช้แล้ว ตั้งแต่เดือนมกราคม 2018 จะไม่มีการคัดค้าน แต่ไม่มีอะไรจะหยุดคุณพิจารณาได้ ไม่ว่าจะจัดหาคุณประโยชน์ใด ๆ ในชีวิตนี้หรือต่อไปเป็นไปไม่ได้ที่จะพูด


5
ฉันไม่เข้าใจความคล้ายคลึงของคุณ
Tunaki

คำถาม "หรือ" ใด ๆ ควรนำเสนอทางเลือกเชิงตรรกะสองแบบซึ่งทั้งสองข้อตอบคำถามเดียวกันเป็นหลัก
ไมค์หนู

ขออภัยดูเหมือนจะมีความรู้อย่างมากในบริบทนี้ แนวคิดคือ "ฉันต้องการใช้Fileฉันควรใช่หรือไม่"
Tunaki

1
ใช่ฉันเห็นด้วยว่าเป็นคำถามที่โหลด ... โดยเฉพาะอย่างยิ่งเนื่องจาก API ของบุคคลที่สามที่มีอยู่จำนวนมากยังคงใช้Fileอยู่ มันจะไม่ตายในเร็ว ๆ นี้
Tunaki

3
it isn't deprecated. But there's nothing to stop you *considering* it soฮ่า ๆ.
Don Cheadle
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.