Why isn't java.io.File deprecated?
从 Java 7 开始就有 java.nio.file 包。那么为什么 java.io.File 在 Java 8 中仍未被弃用?
- Java 对弃用非常保守。
-
@Radiodef 如果不是关于日期:)
-
相关:stackoverflow.com/questions/6903335/java-7-path-vs-file
-
@Radiodef 不同的问题。这是 "NIO.File" 与 "IO.File",链接是 "File" 与 "Path"。两个有趣的问题,但不同。
-
@kervin Path/Files 是 File 的替代品,所以它非常相关。那里有一些关于弃用的讨论,但关于"为什么"的讨论不多。这个问题就像是那个问题的后续问题。
它没有被弃用,因为它没有被破坏。或者更准确地说,因为 Java 团队和/或 Oracle 管理层认为它的破坏程度不足以保证对 File 的弃用会导致的破坏和抵制程度1。
Oracle(和他们之前的 Sun)保留弃用被认为有害/危险使用且在不破坏二进制(或语义)兼容性的情况下无法修复的 API。
java.io.File API 只是老式且笨拙的2,但没有直接危害。还有其他依赖于 File 的标准 API,更不用说许多第 3 方 API 和(可能)数以百万计的客户代码行了。无需向世界发出信号,即所有代码都需要大修。
1 - 显然,有些人会不同意这一点。
2 - @fge 指出某些 File 方法在某些 Java 版本的某些平台(尤其是 Windows / AD)上的行为不正确。然而,那些是/是实现错误,而不是基本的 API 缺陷。在 UNIX / Linux 平台上,方法语义或多或少是正确的2。
3 - 一些"不太正确"的方面是 File.length() 为"/proc"树中的文件返回零,当您访问挂载在 Linux 上的 FAT 文件系统并尝试访问 if 时会发生奇怪的事情来自 Java。
- "因为它没有坏"?那是个笑话,对吧?
-
不,这不是玩笑。 API 并不优雅,也不是(按照今天的标准)设计良好,但 API 方法都按照 javadocs 的描述工作。它们工作的事实意味着它们没有损坏。
-
在编程世界中有很多对"破碎"这个词的双曲使用。但是你不会将一辆 10 年车龄、油耗过多的汽车称为"坏"。这就是我在这里使用的"破碎"的含义。
-
对不起,但即使这样也是错误的。例如,.canWrite() 不像 Windows 上的文档那样工作。 Files.isWritable() 但是。
-
真的吗?但更重要的是,你真的足以证明弃用 File 的痛苦吗?在"破碎"的规模上,这根本不足以证明甚至可以弃用该方法,更不用说整个班级了。此外,可以说是Java on Windows 实现中的缺陷,而不是API 本身。
-
@fge - 如果您指的是这个错误 - bugs.java.com/view_bug.do?bug_id=4939819 - 它已在 Java 7 中修复。
-
好吧,正如我所见,不幸的是,File 将继续存在;但是除了像我这样认真对待文件系统相关工作的人之外,它的无数缺点都没有被注意到;在 JSR 203 之前,我从来没有想过在 Java 中做任何严肃的 fs 工作。从这个意义上说,File 真的很糟糕。而且我相信在引导 Java 用户使用新 API 方面没有付出足够的努力,尽管它已经过时了。
-
至于你提到的错误,不,是相反的; .canWrite() 将返回 true,而实际上用户没有必要的权限。这是在 AD 环境中。
-
@fge - Java 标准的维护者有不同的看法。诚然(2018 年),现在更愿意通过诸如撤回 Applets / JWS、关闭内部 API 等来强制解决问题。但这似乎只有在动机是简化/降低成本/增加 Oracle 收入时才会发生.
因为它在 JDK 中太根深蒂固了。
文件从 Java 早期就已经存在;尽管存在无数缺陷(其中一些在这里列出,但还有其他缺陷),将所有代码迁移到"新"JSR 203 API(已经有 4 年历史!!)所需的工作量是巨大的.
主要问题实际上是对 JSR 203 的认识,或缺乏认识;直到今天,网络上的绝大多数教程仍然使用 File;最好的办法是使用 JSR 203 编写更多教程,使用它等更多代码。
我实际上是新 API 的主要支持者之一,以至于在这方面很烦人 :),但我确实有代码来证明我的观点:
-
通过 FTP 的文件系统,
-
另一个 over Dropbox,
-
另一个通过 box.com,
-
开发新文件系统的辅助库,
-
最后是一个补充 JDK Files 的辅助库(并修复了过程中的一些错误)。
在这个阶段,这是一个耐心的问题;用新的方式回答关于 SO 的问题,甚至是老问题等。这是一场艰苦的战斗。
-
这真的是它不被弃用的原因吗?所有那些使用 File 的 API 仍然可以在弃用的情况下工作,只会在编译时出现警告。
-
@Radiodef 但是有一个(鲜为人知的)事实,即 Path 可以是不在默认文件系统(即您的硬盘)上的实体;这使得 JDK 的一些核心类,例如 FileOutputStream,不能用 JSR 203 重现(这就是为什么有 Files.newOutputStream())。
这不仅仅是遗产。较新的 API 继续使用 File 对象而不是( Path NIO.Files Channel )组合,因为它的 API 更易于理解。
我不提倡使用它。但只是指出,单一的旧文件对象 API 提供了一个单一的点来公开一些寻求简单性的开发人员倾向于使用的 API。
对于许多开发人员来说,很难理解 Path 和 File 之间的区别。它们是两个不同的东西,这就是为什么我们在 java.nio.file.Paths 旁边仍然有 java.nio.file.Files。 Path 就像一个 URI,一个定位器,它不必指向任何东西。而文件是文件系统对象的具体表示。
NIO 将这些概念分开,而旧的 API 将它们全部放在一个对象中。我认为这本身不一定是错误的。它只是在一个 File 对象中捕获了许多有用的 Path 相关 API,该 API 在这些对象之外很有用。
所以我怀疑前进的方向可能是"您需要多少 API?"如果您需要改进 Channels 的功能,增加 Paths 的独立性等,那么 NIO 绝对是没有选择的方法。
如果您是初级开发人员或学生,需要一种快速且基本的面向对象方式来打开文件系统对象并在关闭之前运行一些标准的 FS API 调用,为什么不使用更简单的文件对象呢?毕竟,Java 不只是为专家准备的。