我们可以将您的四种方法分为两种类型:
- 使用内置的标准库方法(例如
File.renameTo()
和Files.move()
)。 - 自己完成工作-通过将字节从源复制到目标。
首先,请注意,
File它没有复制方法,因此在谈论复制时,对于内置的标准库方法只有一个选项。
另请注意,重命名时“自行完成工作”非常不好-
您将复制整个文件,然后删除旧文件。这不是一个好的或有效的方法。在大多数情况下,在同一个文件系统中重命名/移动只需要更改文件元数据而不实际接触内容,因此使用标准库确实要好得多。
因此,您有两种情况:
重命名
这些选项实际上使用
File.renameTo()或
Files.move()。使用流和复制数据毫无意义。
File是过时的课程。它实际上不应该再使用了。为什么有一个很好的解释,可以概括为以下事实:
File当任何标准方法都失败时,它不会为您提供任何信息,而
Files当这种情况发生时,它会为您提供非常准确的异常。
复制中
您有两种选择-使用
Files.copy()或“自己动手”方法之一。
到目前为止,如果要复制的是实际文件,则选择应为
Files.copy()。无需重新发明轮子。它完全符合您的要求,并且有据可查,因此您不太可能偶然引入错误。是的,它非常有效。
Files.copy()依靠底层的“提供者”来进行操作。这意味着有专门的供应商(或操作系统)特定的类来执行对该文件系统最有效的操作。无论是Linux文件系统还是Windows文件系统,副本都将为此进行优化。甚至还有针对特殊情况的提供程序,例如zip文件,因此您可以使用
Files.copy()-
复制zip,jar或war文件中的文件-如果尝试“自己动手”方法,则要复杂得多。
此外,
Files.copy()检查许多在编写“自己的”副本时可能会忘记的事情。例如,您还记得检查过要读取的文件和要写入的文件是否不是同一文件吗?可能会造成严重的麻烦。
Files.copy()可以。它检查权限,检查副本的目标是否是目录,依此类推。因此非常可靠。
那么,为什么您可以选择“自己做”呢?因为好,Java是一种通用语言。您可以选择读取文件,也 可以 选择写入文件,因此 可以
编写自己的“复制”方法。那并不意味着你应该。
请注意,在“方法3”中,“源”文件实际上不是文件!它是由Image
URI产生的,这意味着它可能是网络来源。当您的源文件不是文件,而是基于套接字,数据库BLOB,Web服务器请求等的流或通道时,您将无法真正使用
Files.copy()。这是您需要编写自己的代码的地方。
实际上,
Files还有从文件复制到
OutputStream或从复制到文件的选项
InputStream,因此,如果副本的一侧是流,另一侧是文件,则可以使用该选项。这将是可读,安全的,并抛出有意义的异常。
因此,编写您自己的副本:
- 当您需要将数据从源移动到非文件的目标时,
- 当您需要以某种方式过滤或处理数据,而不是将原样从源复制到目标时,
- 当您使用Java 1.7之前的旧版本时。在这种情况下,频道可能比流更好。



