当前位置: 首页 > 面试题库 >

用Java复制和移动文件,不同方法的解释和比较

谭新知
2023-03-14
问题内容

我实现了文件操作功能,并且我注意到Java提供了多种复制和移动文件的技术。在下面可以找到代码片段,简要描述了这些方法:

方法1:

File from = new File(src.getPath());
File to = new File(dst.getPath());

from.renameTo(to);

方法2:

FileChannel inChannel = new FileInputStream(src).getChannel();
FileChannel outChannel = new FileOutputStream(dst).getChannel();

inChannel.transferTo(0, inChannel.size(), outChannel);

方法3:

InputStream in = getContentResolver().openInputStream(selectedImageUri);
OutputStream out = new FileOutputStream("/sdcard/wallpapers/" + wall);

byte[] buffer = new byte[1024];
int read;

while ((read = in.read(buffer)) != -1) {
    out.write(buffer, 0, read);
}

方法4:

import static java.nio.file.StandardCopyOption.*;

Files.copy(source, target, REPLACE_EXISTING);

所有这些方法都有效,但是我不知道何时应使用它们?从性能和可靠性的角度来看,每种方法的优缺点分别是什么?当我不得不优先使用一种技术而不是另一种技术时,是否有任何特定情况?


问题答案:

我们可以将您的四种方法分为两种类型:

  1. 使用内置的标准库方法(例如File.renameTo()Files.move())。
  2. 自己完成工作-通过将字节从源复制到目标。

首先,请注意,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之前的旧版本时。在这种情况下,频道可能比流更好。


 类似资料:
  • 本文向大家介绍JavaScript实现删除,移动和复制文件的方法,包括了JavaScript实现删除,移动和复制文件的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JavaScript实现删除,移动和复制文件的方法。分享给大家供大家参考。具体如下: 这里利用JavaScript删除、移动和复制文件,运行前请确保文件已经存在,比如在C盘建立test.txt文件,然后在代码里修改为这个路

  • 让我们来看看一些简单的移动可构造和(不是简单的)复制可构造(但仍然是复制可构造的)用户定义(类)类型: 然后,的移动(move-construction或move-assignment)从字面上表示如下:源按位复制到目标,尽管操作名为“move”。在琐碎的移动过程中,右手边(形式上)不是,但整个操作的琐碎性要求右手边(实际)不可变,不是吗?在我看来,这意味着,琐碎的复制操作和琐碎的移动操作在本质上

  • Entry和FileEntry均有copyTo和moveTo方法用来复制和移动目录和文件。 Entry.copyTo(newEntry, 'new_Entry_name', function(copiedEntry){ console.log('Entry moved.'); }, errorHandler); Entry.moveTo(newEntry, 'new_Entry_name

  • 问题 你想要复制或移动文件和目录,但是又不想调用shell命令。 解决方案 shutil 模块有很多便捷的函数可以复制文件和目录。使用起来非常简单,比如: import shutil # Copy src to dst. (cp src dst) shutil.copy(src, dst) # Copy files, but preserve metadata (cp -p src dst)

  • 问题内容: 是否有一个标准的Java库可以处理常见的文件操作,例如移动/复制文件/文件夹? 问题答案: 这是通过操作执行此操作的方法:

  • 问题内容: 我有一个文件 example.tar.gz ,我需要将其复制到另一个具有不同名称示例 _test.tar.gz的 位置。我尝试过 哪里 然后 没用 路径正确。它打印该文件存在。有谁能够帮我? 问题答案: 为什么要重新发明轮子,只需使用 ,这将为您处理许多情况