【问题标题】:Java : copy files efficiently with channelJava:使用通道有效地复制文件
【发布时间】:2017-10-24 07:57:51
【问题描述】:

我读了一篇关于转移副本的文章 在https://www.ibm.com/developerworks/library/j-zerocopy/。建议用户通道进行 IO 操作。

有一个可用的复制文件操作的基准 https://baptiste-wicht.com/posts/2010/08/file-copy-in-java-benchmark.html

根据基准,我可以使用 nio buffernio trasfer

我还阅读了 FileChannel 在操作系统级别进行缓冲 这里How to implement a buffered / batched FileChannel in Java?

用缓冲区或不带缓冲区复制文件的效率更高。

nio 缓冲区代码

public static void nioBufferCopy(File sourceFile, File targetFile, int BUFFER) {
        FileChannel inputChannel = null;
        FileChannel outputChannel = null;
        try {
            inputChannel = new FileInputStream(sourceFile).getChannel();
            outputChannel = new FileOutputStream(targetFile).getChannel();
            ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER);
            while (inputChannel.read(buffer) != -1) {
                buffer.flip();          
                while(buffer.hasRemaining()){
                    outputChannel.write(buffer);
                }           
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
           //close resource
        }
}

nio 传输代码

public void copyFileWithChannels(File aSourceFile, File aTargetFile) {              
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        FileInputStream inStream = null;
        FileOutputStream outStream = null;      
        try {
            inStream = new FileInputStream(aSourceFile);
            inChannel = inStream.getChannel();
            outStream = new  FileOutputStream(aTargetFile);        
            outChannel = outStream.getChannel();
            long bytesTransferred = 0;
            while(bytesTransferred < inChannel.size()){
                bytesTransferred += inChannel.transferTo(bytesTransferred, inChannel.size(), outChannel);
            }
        }       
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            //close resource
        }              
}

【问题讨论】:

  • FileChannel 不在操作系统中进行缓冲,超出了操作系统对任何打开文件所做的缓冲。您的第一个代码不是最佳的,但是。传输 API 被认为是最有效的,
  • 如果你想要真正高效的文件复制,那么 java 是不适合这项工作的工具。在 unix 上,您将希望在可用的情况下使用 reflink 副本,并在其他情况下探测稀疏文件中的漏洞。在 linux 上,拼接 + 管道技巧可以避免复制到用户空间。但是这些东西都没有在 java 标准库中公开。好吧,使用一些 JNA 或 JNR 胶水,当然可以在 java 中使用。

标签: java io nio file-copying


【解决方案1】:

之前有人问过这个问题:

Java NIO FileChannel versus FileOutputstream performance / usefulness

TL.DR.:您的 JVM 运行在什么上很重要,但大多数情况下,java.nio 会稍微快一些。

【讨论】:

    猜你喜欢
    • 2010-12-14
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    相关资源
    最近更新 更多