欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

【Java】文件复制的各种姿势,java复制姿势

来源: javaer 分享于  点击 36274 次 点评:286

【Java】文件复制的各种姿势,java复制姿势


下面讲解一下Java中复制文件的各种姿势。

1. BIO

第一种是传统IO操作方式,即输入输出流配合,一个读一个写,相对简单

public static void copyFile(String s, String d) {
        int readPerSize = 1024 * 1024;
        try (FileInputStream in = new FileInputStream(s);
             FileOutputStream out = new FileOutputStream(d);) {
            byte[] buffer = new byte[readPerSize];
            int len = 0;
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2. NIO Buffer

  • 从 FileInputStream 获取 FileChannel;
  • 创建 Buffer(ByteBuffer的allocateallocateDirect方法,一个是堆内存,一个是本地内存);
  • 将数据从 FileChannel 读到 Buffer 中,并通过返回值大小判断Buffer大小;
  • 同时切换读模式 filp,然后写入FileOutputStream的 FileChannel中;
  • 缓存清除;
  • FileChannel关闭;
    public static void copyFileByByteBuffer(String source, String dest, ByteBuffer buffer) {
        try (FileInputStream in = new FileInputStream(source);
             FileOutputStream out = new FileOutputStream(dest);
        ) {
            FileChannel inChannel = in.getChannel();
            FileChannel outChannel = out.getChannel();
            int size = inChannel.read(buffer);
            while (size > -1) {
                buffer.flip();
                outChannel.write(buffer);
                buffer.clear();
                size = inChannel.read(buffer);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            buffer.clear();
        }
    }

3. NIO Channel

Buffer方式类似,但是复制过程通过outChanneltransferFrominChanneltransferTo实现

    public static void copyFileByChannel(String s, String d, ByteBuffer buffer) {
        int readPerSize = 1024 * 1024;
        try (FileInputStream in = new FileInputStream(s);
             FileOutputStream out = new FileOutputStream(d);){
            FileChannel inChannel = in.getChannel();
            FileChannel outChannel = out.getChannel();
            int pos = 0;
            // 也可以通过 inChannel 的 transferTo 去写入
            while (pos < inChannel.size()) {
                pos += outChannel.transferFrom(inChannel, pos, readPerSize);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

4. NIO 文件内存映射

    public static void copyFileByDirectBuffer(String s, String d) {
        int readPerSize = 1024 * 1024;
        try {
            FileChannel inChannel = new RandomAccessFile(s,"r").getChannel();
            FileChannel outChannel = new RandomAccessFile(d,"rw").getChannel();
            long fileSize = inChannel.size();
            int pos = 0;
            while (pos < fileSize) {
                long copyFileSize = Math.min((fileSize-pos),readPerSize);
                //得到的是DirectByteBuffer
                MappedByteBuffer byteBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE,pos,copyFileSize);
                inChannel.read(byteBuffer);
                pos += byteBuffer.position();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

5. 终极大招

JDK7提供了一个文件操作的工具类 —- Files

File提供了诸如:copy / delete / move / read 等各种静态方法,对文件的操作进一步封装。

有了这些方法,就不需要我们手动的去操作输入输出流,读写操作等,实乃良心。

Files.copy(Paths.get("E:\\Book\\ Vim实用技巧.pdf"),Paths.get("D:\\Vim实用技巧.pdf"));

引用

《Java特种兵·上册》 第四章

相关文章

    暂无相关文章
相关栏目:

用户点评