随笔都是学习笔记
随笔仅供参考,为避免笔记中可能出现的错误误导他人,请勿转载。

需求分析:

  - 需要实现文件的拷贝操作,那么这种拷贝就有可能拷贝各种类型的文件,所以使用字节流;

  - 在进行拷贝的时候有可能需要考虑到大文件的拷贝问题;

方案设计:

  - 方案一:一次性全部拷贝;

    |- 如果拷贝的文件很大则此方法不可取,会导致程序崩溃

  - 方案二:读取一部分输出一部分;

    核心的操作:

      |- InputStream: public int read(byte[] b) throws IOException;
      |- OutputStream: public void write(byte[] b,int off,int len) throws IOException;

一个简单的文件拷贝操作:

import java.io.*;

class FileUntil {    // 定义一个文件操作的工具类
    private File srcFile;   // 源文件路径
    private File desFile;   // 目标文件路径

    public FileUntil(File srcFile,File desFile){
        this.srcFile = srcFile;
        this.desFile = desFile;
    }
    // 文件的拷贝方法
    public boolean copy() throws IOException {
        if (!this.srcFile.exists()){
            System.out.println("源文件不存在!!");
            return false;
        }
        if (!this.desFile.getParentFile().exists()){ // 如果目录不存在
            this.desFile.getParentFile().mkdirs();   // 创建父目录
        }
        byte[] data = new byte[1024];   // 开辟拷贝的缓冲区
        InputStream input = null;
        OutputStream output = null;
        try {
            // 创建字节流对象
            input = new FileInputStream(this.srcFile);
            output = new FileOutputStream(this.desFile);

            // 获取文件长度
            int len = 0;
            // 1.读取数据到数组之中,随后返回读取的个数,len = input.read(data)
            // 2.判断个数是否是 -1,如果不是则进行写入,len = input.read(data) != -1
            while ((len = input.read(data)) != -1){ // 拷贝的内容都在data数组里面
                output.write(data,0,len);
            }
            return true;
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (input != null){
                input.close();
            }
            if (output != null){
                output.close();
            }
        }
        return false;
    }
}
public class MAIN {
    public static void main(String[] args){
        long start = System.currentTimeMillis();
        File src= new File("D:" + File.separator + "Demo_2_15" + File.separator + "Writer.txt");
        File des= new File("D:" + File.separator + "Demo_2_15" + File.separator + "Copy.txt");
        FileUntil fu = new FileUntil(src,des);
        try {
            fu.copy();
        } catch (IOException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("拷贝完成、用时:" + (end - start) + "ms");
    }
}

以上属于文件拷贝最原始的实现方式,从JDK1.9开始InputStream和Reader类中都追加有数据转存的处理操作方法:

InputStream: public long transferTo(OutputStream out) throws IOException;
Reader: public long transferTo(Writer out ) throws IOException;

使用上诉转存的操作处理:

import java.io.*;

class FileUntil {    // 定义一个文件操作的工具类
    private File srcFile;   // 源文件路径
    private File desFile;   // 目标文件路径

    public FileUntil(File srcFile,File desFile){
        this.srcFile = srcFile;
        this.desFile = desFile;
    }
    // 文件的拷贝方法
    public boolean copy() throws IOException {
        if (!this.srcFile.exists()){
            System.out.println("源文件不存在!!");
            return false;
        }
        if (!this.desFile.getParentFile().exists()){ // 如果目录不存在
            this.desFile.getParentFile().mkdirs();   // 创建父目录
        }
        InputStream input = null;
        OutputStream output = null;
        try {
            // 创建字节流对象
            input = new FileInputStream(this.srcFile);
            output = new FileOutputStream(this.desFile);

            input.transferTo(output);
            return true;
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (input != null){
                input.close();
            }
            if (output != null){
                output.close();
            }
        }
        return false;
    }
}
public class MAIN {
    public static void main(String[] args){
        long start = System.currentTimeMillis();
        File src= new File("D:" + File.separator + "Demo_2_15" + File.separator + "Writer.txt");
        File des= new File("D:" + File.separator + "Demo_2_15" + File.separator + "Copy.txt");
        FileUntil fu = new FileUntil(src,des);
        try {
            fu.copy();
        } catch (IOException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("拷贝完成、用时:" + (end - start) + "ms");
    }
}

 这种方法的性能更好,但是需要更高的JDK版本要求。

 

连带目录的拷贝功能:

import java.io.*;
import java.lang.reflect.Field;

class FileUntil {    // 定义一个文件操作的工具类
    private File srcFile;   // 源文件路径
    private File desFile;   // 目标文件路径

    public FileUntil(File srcFile,File desFile){
        this.srcFile = srcFile;
        this.desFile = desFile;
    }
    public boolean copyDir() throws IOException{
        if (!this.srcFile.exists()){
            System.out.println("拷贝目录不存在!");
            return false;
        }
        try {
            this.copyDirImpl(this.srcFile);
            return true;
        }catch (Exception e){
            return false;
        }
    }
    private boolean copyDirImpl(File file) throws IOException{
        if (file.isDirectory()){    // 是目录
            File[] allDir = file.listFiles();   // 列出目录下所有内容
            System.out.println(allDir.length);
            if (allDir != null){    // 如果目录不为空
                for (File dir : allDir) {   // 遍历目录
                    copyDirImpl(dir);       // 递归操作
                }
            }
        }else{  // 是文件
            String newfilePath = file.getPath().replace(this.srcFile.getPath() + File.separator,"");    // 替换文件路径的父路径,找到文件名
            System.out.println(newfilePath);
            File newFile = new File(this.desFile,newfilePath);  // 将目标路径作为父路径
            this.copyFileImpl(file,newFile);    // 调用拷贝方法
        }
        return false;
    }

    private boolean copyFileImpl(File srcFile, File desFile) throws IOException{
        if (!desFile.getParentFile().exists()){ // 如果目录不存在
            desFile.getParentFile().mkdirs();   // 创建父目录
        }
        InputStream input = null;
        OutputStream output = null;
        try {
            // 创建字节流对象
            input = new FileInputStream(srcFile);
            output = new FileOutputStream(desFile);
            input.transferTo(output);     // 直接使用转存方法
            return true;
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (input != null){
                input.close();
            }
            if (output != null){
                output.close();
            }
        }
        return false;
    }
    // 文件的拷贝方法
    public boolean copyFile() throws IOException {
        if (!this.srcFile.exists()){
            System.out.println("源文件不存在!!");
            return false;
        }
        return this.copyFileImpl(this.srcFile,this.desFile);
    }
}
public class MAIN {
    public static void main(String[] args){
        long start = System.currentTimeMillis();
//        File src= new File("D:" + File.separator + "Demo_2_15" + File.separator + "Writer.txt");
        File src= new File("D:" + File.separator + "Demo_2_15");    // 源目录
        File des= new File("D:" + File.separator + "Demo_2_17");    // 目标目录
        FileUntil fu = new FileUntil(src,des);
        try {
            if (src.isFile()){  // 文件拷贝
                System.out.println(fu.copyFile()? "拷贝成功" : "拷贝失败");
            }else { // 目录拷贝
                System.out.println(fu.copyDir()? "拷贝成功" : "拷贝失败");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("拷贝完成、用时:" + (end - start) + "ms");
    }
}

 

 

posted on 2022-02-17 13:47  时间完全不够用啊  阅读(104)  评论(0编辑  收藏  举报