为什么 java.io.File 没有被弃用?

5

自从Java 7以来,就有了java.nio.file包。那么为什么在Java 8中java.io.File仍然没有被弃用呢?


3
Java在废弃方面非常保守。 - Radiodef
@Radiodef 如果不涉及日期的话 :) - Dmitry Ginzburg
1
相关:https://dev59.com/QWw05IYBdhLWcg3w_Gyw - Radiodef
@Radiodef 不同的问题。这是关于"NIO.File"与"IO.File"的,链接是"File"与"Path"。两个有趣的问题但不同。 - kervin
@kervin Path/FilesFile的替代品,因此它们非常相关。关于弃用有一些讨论,但不太涉及“为什么”。这个问题就像那个问题的后续。 - Radiodef
3个回答

8
它没有被弃用是因为它没有出现问题。更确切地说,是因为Java团队和/或Oracle管理层认为它没有足够的问题来引起弃用File所产生的破坏和阻力。
Oracle(以及其前身Sun)将弃用保留给那些被认为对使用者有害/危险且不可能在不破坏二进制(或语义)兼容性的情况下修复的API。
java.io.File API仅仅是过时而且笨拙,但并非直接有害。有其他标准API依赖于File,更不要说许多第三方API和(可能)数亿行的客户代码了。没有必要向全世界发出信号,表明所有这些代码都需要重构。
1 - 显然,有些人会反对这一点。
2 - @fge指出,一些File方法在一些Java版本的某些平台上(尤其是Windows / AD)表现不正确。但是,那些只是实现缺陷,而非基本API缺陷。在UNIX / Linux平台上,方法的语义基本上是正确的。
3 - 一些“不太正确”的方面是,File.length()返回"/proc"树中文件的零,并且当您尝试从Java访问Linux上挂载的FAT文件系统时会发生奇怪的事情。

2
“因为它没有坏掉?” [这是个笑话,对吧?] (http://java7fs.wikia.com/wiki/Why_File_sucks) - fge
2
不,这不是一个玩笑。虽然API不够优雅,也不符合(今天的标准)良好设计的要求,但是API方法都按照javadocs所描述的方式正常工作。它们能够正常工作的事实意味着它们并没有出现故障。 - Stephen C
在编程世界中,“破损”一词被过度使用。但是你不会称一个10年旧、油耗过多的汽车为“破损”。而这正是我在这里使用“破损”的含义。 - Stephen C
我认为,不幸的是,“File”已经成为了必须存在的一部分;但它无数的缺点却只有像我这样认真对待文件系统相关工作的人才会注意到;在JSR 203之前,我从未想过在Java中进行任何严肃的文件系统工作。从这个意义上说,“File”确实是有问题的。而且我认为,尽管新API已经存在很长时间,但并没有投入足够的努力来引导Java用户使用它。 - fge
关于您提到的错误,不是这样的;.canWrite()会返回true,但实际上用户没有必要的权限。这是在AD环境中发生的。 - fge
显示剩余4条评论

3

因为它太深入了JDK。

自Java早期以来,文件就一直存在;尽管它有无数缺陷(其中一些列在此处,但还有其他问题),将所有代码迁移到“新”的JSR 203 API(已经4年了!)所需的工作量是巨大的。

实际上,主要问题在于JSR 203的知晓度或缺乏知晓度;即使在今天,绝大多数网上教程仍在使用File;最好的办法就是编写更多使用JSR 203的教程、代码等等。

事实上,我是这个新API的主要倡导者之一,甚至在这个方面有点烦人:),但我有代码证明我的观点:

现在,这只是一个耐心的问题;使用新方法回答SO上的问题,甚至是旧问题等等。这是一场艰苦的战斗。


1
这真的是它没有被弃用的原因吗?所有使用File的API仍将在弃用时工作,只会编译警告。 - Radiodef
@Radiodef,然而有一个(鲜为人知的)事实是,Path 可以是一个不在默认文件系统上的实体,例如你的硬盘;这使得 JDK 的一些核心类,例如 FileOutputStream,无法使用 JSR 203 进行再现(这就是为什么有 Files.newOutputStream() 的原因)。 - fge

2
不仅是传统遗留问题。新一代API继续使用File对象而非(Path + NIO.Files + Channel)组合,因为它是更简单易懂的API。 我并不主张使用它。只是指出单个旧的File对象API提供了一个公开API的单一点,一些寻求简化的开发者会倾向于使用它。 对于许多开发者来说,理解Path和File之间的区别比较困难。它们是两个不同的东西,这就是为什么我们仍然在java.nio.file中有Files和Paths。Path就像URI、定位器一样,它不必指向任何东西。而File则是文件系统对象的具体表示。 NIO将这些概念分离,而旧API将它们都放在一个对象中。我不认为这本质上是错误的。它只是将许多有用的Path相关API陷入了File对象中,在这些对象之外这些API也很有用。 因此,我认为前进的方式可能是“你需要多少API?”如果你需要Channels的改进功能、Paths的独立性等,则无选择地必须使用NIO。 如果你是一名初级开发者或学生,需要一种快速基本的面向对象的方法来打开文件系统对象并运行一些标准FS API调用,为什么不使用更简单的File对象呢?毕竟,Java不仅仅是为专家而设计的。

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