Java有几种文件拷贝方式?(二)

Java IO/NIO 源码结构
前面我在典型回答中提了第三种方式,即 Java 标准库也提供了文件拷贝方法(java.nio.file.Files.copy)。如果你这样回答,就一定要小心了,因为很少有问题的答案是仅仅调用某个方法。从面试的角度,面试官往往会追问:既然你提到了标准库,那么它是怎么实现的呢?有的公司面试官以喜欢追问而出名,直到追问到你说不知道。

其实,这个问题的答案还真不是那么直观,因为实际上有几个不同的 copy 方法。

public static Path copy(Path source, Path target, CopyOption... options)
    throws IOException
public static long copy(InputStream in, Path target, CopyOption... options)
    throws IOException
public static long copy(Path source, OutputStream out) 
throws IOException
 

可以看到,copy 不仅仅是支持文件之间操作,没有人限定输入输出流一定是针对文件的,这是两个很实用的工具方法。

后面两种 copy 实现,能够在方法实现里直接看到使用的是 InputStream.transferTo(),你可以直接看源码,其内部实现其实是 stream 在用户态的读写;而对于第一种方法的分析过程要相对麻烦一些,可以参考下面片段。简单起见,我只分析同类型文件系统拷贝过程。

public static Path copy(Path source, Path target, CopyOption... options)
    throws IOException
 {
    FileSystemProvider provider = provider(source);
    if (provider(target) == provider) {
        // same provider
        provider.copy(source, target, options);// 这是本文分析的路径
    } else {
        // different providers
        CopyMoveHelper.copyToForeignTarget(source, target, options);
    }
    return target;
}
我把源码分析过程简单记录如下,JDK 的源代码中,内部实现和公共 API 定义也不是可以能够简单关联上的,NIO 部分代码甚至是定义为模板而不是 Java 源文件,在 build 过程自动生成源码,下面顺便介绍一下部分 JDK 代码机制和如何绕过隐藏障碍。

首先,直接跟踪,发现 FileSystemProvider 只是个抽象类,阅读它的源码能够理解到,原来文件系统实际逻辑存在于 JDK 内部实现里,公共 API 其实是通过 ServiceLoader 机制加载一系列文件系统实现,然后提供服务。

我们可以在 JDK 源码里搜索 FileSystemProvider 和 nio,可以定位到sun/nio/fs,我们知道 NIO 底层是和操作系统紧密相关的,所以每个平台都有自己的部分特有文件系统逻辑。

省略掉一些细节,最后我们一步步定位到 UnixFileSystemProvider → UnixCopyFile.Transfer,发现这是个本地方法。

最后,明确定位到UnixCopyFile.c,其内部实现清楚说明竟然只是简单的用户态空间拷贝!
————————————————
版权声明:本文为CSDN博主「雪蛋不是蛋(^_−)☆」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_46291038/article/details/120407035

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值