Java:路径 vs 文件

238

对于使用Java 7编写的新应用程序,是否还有使用java.io.File对象的理由?还是可以将其视为已被弃用?

我认为java.nio.file.Path可以完成所有java.io.File所能做的事情,并且更加强大。

8个回答

193

简而言之:

java.io.File 很可能永远不会被弃用 / 不被支持。 也就是说,java.nio.file.Path 是更现代的 java.nio.file 库的一部分,它可以完成 java.io.File 可以做到的所有事情,并且通常以更好的方式和更多功能实现。

对于新项目,请使用 Path

如果您需要遗留的 File 对象,只需调用 Path#toFile()

从 File 迁移到 Path

这个 Oracle 页面突出显示了不同之处,并将 java.io.File 功能 映射到 java.nio.file lib(包括 Path)功能

Janice J. Heiss 和 Sharon Zakhour 在 2009 年 5 月发表的文章,讨论 JDK 7 中的 NIO.2 文件系统


15
您可以在此处阅读Oracle对差异的评论:http://docs.oracle.com/javase/tutorial/essential/io/legacy.html。 - Josiah Yoder
4
请注意,“Files”(复数形式)并未被弃用。它本质上是一个在路径对象上操作并执行旧的File类的许多功能(例如isDirectory()或exists())的抽象类。 - Josiah Yoder
4
现在我想知道:为什么JavaFX 8中的新文件/文件夹选择器对话框仍然使用File而不是Path - piegames
2
路径是一个接口。要创建一个实例,请使用Paths.get(filename)。由于需要编写Files.exists(Paths.get(filename))而不是new File(filename).exists()才能引起困惑,所以仍在使用旧的API。 - Josiah Yoder
Path 可以更容易地通过 resolve(...) 添加子路径,或者通过 getParent() 上移一个级别,等等进行修改。而 File 则不能。基本上,一旦您完成了对 Path 的修改,您通常会将其转换为 toFile(),以便将其发送到旧方法中,例如 FileInputStream 构造函数。 - MasterHD

17

我们能不能将它视为已被弃用?

不行,除非在File Javadoc中标记了它已被弃用,否则你不能将其视为已被弃用。


17
即使这是一个“因为RFC这样说”的答案之一,我也不认为这是一个好的答案。很明显,File将会被Path所取代。如果你想走在时代前沿,你可以立即开始使用Path,并在需要时使用toFile()。 - Chris
16
自从1.02版本更改了AWT事件模型以来,JDK中从未删除过任何内容。这一点并不'明显',事实上它是错误的。 - user207421
5
@downvoters 这个答案本质上是一个重言式,它不可能是错误的。值得注意的是,在我写下这个答案的五年里,Java 8已经出现了,java.io.File仍然没有被删除,甚至没有过时,Javadoc中也没有任何迹象表明这些事情会发生。 - user207421
2
@EJP,我刚刚点赞了你的评论。但是,当您说答案是重言时,我不完全确定您是否正确。这个问题可能应该被视为“基于观点”,问题是“我们可以考虑它已被弃用”。好吧,是的,OP和其他任何人都可以考虑,但事实上并没有。 - mike rodent
@mikerodent,我不理解你的最后一句话。你不知道OP会或不会“提出”什么。而且我认为“can”的存在并没有实质性的区别。 - user207421
显示剩余4条评论

11

请问能否更新链接?我想阅读这篇文章。 - John B
很遗憾,我无法在Oracle网页上找到原始文章。这是来自Wayback Machine的版本:http://web.archive.org/web/20090601091119/http://java.sun.com/developer/technicalArticles/javase/nio/ - LordDoskias
1
我在普通的Oracle网站上再次找到了这篇文章 - 已经添加了答案链接。 - Duncan Jones

8

我将完成@mmcrae的非常好的回答。

是否还有使用java.io.File对象的理由,或者我们可以认为它已经过时了?

JDK类很少被弃用。
您可以在JDK 8 API弃用列表中查看自第一个JDK以来被弃用的所有类。
它仅包含Oracle文档和Java社区不建议使用的少部分类。
java.util.Datejava.util.Vectorjava.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的Oracle教程证实了您的想法。

在Java SE 7发布之前,java.io.File类是文件I/O的机制,但它有几个缺点。许多方法在失败时没有抛出异常,因此无法获得有用的错误消息。例如,如果文件删除失败,程序将收到“删除失败”,但不知道是因为文件不存在、用户没有权限还是其他问题。重命名方法在各个平台上的工作不一致。没有对符号链接的真正支持。需要更多支持元数据,如文件权限、文件所有者和其他安全属性。访问文件元数据效率低下。许多File方法不能扩展。请求服务器上的大型目录列表可能导致挂起。大型目录也可能导致内存资源问题,从而导致拒绝服务攻击。无法编写可靠的代码,以递归方式遍历文件树,并在存在循环符号链接时做出适当响应。
由于java.io.File存在这么多缺点,我们没有理由在新开发中使用这个类。即使是使用java.io.File的旧代码,Oracle也建议使用Path。
也许您有使用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);

简而言之,如果她/他愿意,确实可以将其视为已弃用。 - mike rodent
@mike rodent。没错。从概念上讲,她/他应该这样做,但出于已解释的原因,在Javadoc方面并非如此。 - davidxxx

5

是的,但是许多现有的API,包括Java7自身的标准API,仍然只能使用File类型。


8
使用Path.toFile()方法可以将Path对象转换为File对象,然后使用标准API。 - jacktrades
3
你的回答是“是但也不是”吗? - user207421

3

Java.io.File没有被弃用。是的,java.nio.file.Path更好,但只要还有大量程序和教科书使用Java.io.File,即使出于遗留原因,也不应该被视为已弃用,因为它太重要了。这样做只会毫无意义地给自己找麻烦。例如,Android框架使用File来处理一些基本的文件操作功能,其他许多东西也是如此。


1
他没有问Path是否更好,他问的是File是否已经被弃用。 - user207421
3
@EJP,我认为你有点太过于小心翼翼。楼主确实问了java.io.File是否已经过时,而我回答了这个问题。他还说“我相信java.nio.file.Path可以做java.io.File所能做的一切,而且更多。” 我只是在确认他的评论,这不值得被投票否决。 - Andrew S

-1

众所周知,java.nio包中的类使用Path实例而不是File实例。如果可能的话,建议在使用java.nio时使用Path类。

现在有时您必须使用File类。这是因为方法或构造函数需要File实例作为参数,但当您有选择时,请确保使用Path而不是File


-10
对于使用Java 7编写的新应用程序,是否还有理由使用java.io.File对象,或者我们可以将其视为已弃用?
这有点像在说:“拿破仑应该入侵俄罗斯,还是这些布鲁塞尔芽菜真的很好吃?”
至于问题的第二部分,您确实可以将其视为已弃用。截至2018年1月,它尚未被弃用。但是没有任何阻止您考虑它。无论这会不会在此生或来世中给您带来任何优势都是不可能的。

7
我不理解你的类比。 - Tunaki
任何“或”问题都应该提供两个逻辑上的选择,两个选项本质上回答了同一个问题。 - mike rodent
抱歉,在这种情况下听起来有点学究。意思是“我想使用File。我应该使用吗,是或否?” - Tunaki
不会被冒犯。问题的提出方式邀请分析它“真正”想问什么,而你已经给出了一个合理的解释。但这是一个有偏见的问题。通过指出其奇怪的本质,我只是引起注意,实际上它应该被压缩为“基于意见的”。至于你的问题:“是的”。你说你想用,那就用吧。原帖的作者希望有人能说“不要使用File,它有点垃圾”,但File五年甚至更长时间后仍然存在。也许我们应该庆祝一下? - mike rodent
1
是的,我同意这是一个棘手的问题...特别是因为许多现有的第三方API仍然使用“File”。它不会很快消失。 - Tunaki
3
它并没有过时。但是没有任何阻止你考虑它已经过时。LOL. - Don Cheadle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接