Hadoop FileUtil.copy 签名

Hadoop FileUtil.copy signature

在 Hadoop 2.2.0 (hadoop-common) 中,我看到 FileUtil.copy 的以下签名和文档:

 /** Copy files between FileSystems. */
 public static boolean copy(FileSystem srcFS, Path src, 
                            FileSystem dstFS, Path dst, 
                            boolean deleteSource,
                            Configuration conf) throws IOException {

我应该如何理解 boolean 和同时发生的 IOException?是不是为了根据对IOException的具体理解,区分两个类可能的错误?

在源代码中,使用了false if (!dstFS.mkdirs(dst)) 但是 IOException 被抛出 if (!dstFS.exists(dst)) (例如)。

同时 return 一个状态值和抛出异常是常见的做法吗?处理这两者的客户端代码变得很麻烦...

这种方法在 Apache Hadoop 的历史上已经很古老了。方法签名样式至少可以追溯到 2006 年,当时该项目从 Apache Nutch 中分离出来。

https://github.com/apache/hadoop-common/blob/9d5bba827967a12bf6182029235df46645eb4264/src/java/org/apache/hadoop/fs/FileUtil.java

(方法名不同,但签名风格相同。)

我在我们的开发历史中找不到任何关于方法签名样式的具体讨论。我认为一个合理的理论是,这遵循 JDK File API 中的类似约定。 boolean return 值与基础 mkdirsdelete 操作失败的情况相关。同样,java.io.File#delete and java.io.File#mkdirs 使用 boolean return 代码来传达失败。 Hadoop 方法很可能遵循这种风格,然后还使用 IOException 来处理额外的逻辑错误和真正的 I/O 错误,例如无法与 NameNode 等远程守护进程建立网络连接。

我不会说这种方法签名风格是常见做法或良好做法。正如您所说,它使客户端代码的错误处理变得复杂。 JDK 7 似乎已经认识到这些操作使用boolean return代码的弱点,因为它无法区分失败的具体原因。在 Java 7 中启动的 NIO 文件 API 中的等效方法,例如 java.nio.file.Files#delete and java.nio.file.Files#createDirectory,选择使用特定的异常类型来报告不同情况的错误(并删除 boolean return)。 Apache Hadoop 社区最近有一些关于效仿我们自己的 API 设计的讨论。

出于向后兼容的原因,当前的方法签名不太可能改变,甚至变得更好。根据我们的 Compatibility 政策,我们可能会选择在主要版本边界上对其进行修改,但这将具有挑战性。