Java基础-使用流实现文件拷贝

1.文件流

Java中,文件的输入和输出是通过流(Stream)来实现的。流按照处理数据的单位,可以分为字节流和字符流。字节流的处理单位是字节,通常用来处理二进制文件,例如音乐、图片文件等。而字符流的处理单位是字符,通常用来处理文本文件。

2.文件流的继承关系

文件流类继承关系图

字节流:以输入流(InputStream)、输出流(OutputStream)为基类,所有的字节流类都直接或间接继承InputStream或OutputStream 这两个抽象类,如直接继承InputStream的有:FileInputStream、ByteArrayInputStream、ObjectInputStream、PipeInputStream、SequenceInputStream;字节缓冲流BufferedInputStream,BufferedOutputStream分别间接继承nputStream或OutputStream。

字符流:以字符输入流(Reader)、字符输出流(Writer)为基类,所有的字符流类都都直接或间接继承Reader或 Writer 这两个抽象类,其中Reader是用于读取字符流的抽象类,Writer是用于写入字符流的抽象类。如:FileReader、CharArrayReader、PipedReader、StringReader。字符缓冲流BufferedReader和BufferedWriter间接继承Reader或 Writer。

3.文件读写的基本流程

步骤1.使用File类;

步骤2.使用字节流或者字符流的子类;

步骤3.进行读/写操作;

步骤4.关闭输入/输出。

如:

        InputStream in = null;
        // 1.使用File类
        File f = new File("F:\\Temp\\1.txt");
        int totalLen = 0;
        try {
            // 2.指定字节流
            in = new FileInputStream(f);
            // 临时的字节数组,每次最多读取1024字节
            byte[] b = new byte[1024];
            // 实际每次读取的字节数
            int temp = 0;
            // 3.进行读操作
            while ((temp = in.read(b)) != -1) {
                totalLen = totalLen + temp;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4.关闭流
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("字节读取文件:" + totalLen);

4.Demo演示

文件简单拷贝(分别以字节流,字符流,字节缓冲流,字符缓冲流实现文件拷贝)。

package com.yx.filedemo;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;

/**
 * FileReadWrite
 *
 * @author yx
 * @date 2019/12/7 10:40
 */
public class CopyFile {
    public static void main(String[] args) {
        copyFile1("F:\\Temp\\a.txt", "F:\\Temp2\\1.txt");
        copyFile2("F:\\Temp\\a.txt", "F:\\Temp2\\2.txt");
        copyFile3("F:\\Temp\\a.txt", "F:\\Temp2\\3.txt");
        copyFile4("F:\\Temp\\a.txt", "F:\\Temp2\\4.txt");
    }

    /**
     * 以字节流方式实现文件的拷贝
     *
     * @param src  源文件
     * @param dest 目标文件
     */
    private static void copyFile1(String src, String dest) {
        InputStream in = null;
        OutputStream out = null;
        // 1.使用File类
        File fa = new File(src);
        if (!fa.exists() || !fa.isFile()) {
            return;
        }
        File fb = new File(dest);
        if (fb.getParentFile() != null && !fb.getParentFile().exists()) {
            fb.getParentFile().mkdirs();
        }
        int totalLen = 0;
        try {
            // 2.指定字节流
            in = new FileInputStream(fa);
            out = new FileOutputStream(fb);
            // 临时的字节数组,每次最多读取1024字节,可适当修改加快读写性能
            byte[] b = new byte[1024];
            // 实际每次读取的字节数
            int temp = 0;
            // 3.进行读操作
            while ((temp = in.read(b)) != -1) {
                totalLen = totalLen + temp;
                out.write(b, 0, temp);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4.关闭流
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("以字节流方式实现文件的拷贝,拷贝字节数:" + totalLen);
    }

    /**
     * 以字符流方式实现文件的拷贝
     *
     * @param src  源文件
     * @param dest 目标文件
     */
    private static void copyFile2(String src, String dest) {
        Reader reader = null;
        Writer writer = null;
        // 1.使用File类
        File fa = new File(src);
        File fb = new File(dest);
        if (!fa.exists() || !fa.isFile()) {
            return;
        }
        if (fb.getParentFile() != null && !fb.getParentFile().exists()) {
            fb.getParentFile().mkdirs();
        }
        try {
            // 2.指定字节流
            reader = new FileReader(fa);
            writer = new FileWriter(fb);
            char[] chars = new char[50];
            int i;
            // 3.进行读写操作
            while ((i = reader.read(chars)) != -1) {
                writer.write(chars, 0, i);
                writer.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4.关闭流
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("以字符流方式实现文件的拷贝");
    }

    /**
     * 以字节缓冲流实现文件的拷贝
     *
     * @param src  源文件
     * @param dest 目标文件
     */
    private static void copyFile3(String src, String dest) {
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        // 1.使用File类
        File fa = new File(src);
        if (!fa.exists() || !fa.isFile()) {
            return;
        }
        File fb = new File(dest);
        if (fb.getParentFile() != null && !fb.getParentFile().exists()) {
            fb.getParentFile().mkdirs();
        }
        int totalLen = 0;
        try {
            // 2.指定字节流
            bis = new BufferedInputStream(new FileInputStream(fa));
            bos = new BufferedOutputStream(new FileOutputStream(fb));
            // 临时的字节数组,每次最多读取1024字节,可适当修改加快读写性能
            byte[] b = new byte[1024];
            // 实际每次读取的字节数
            int temp = 0;
            // 3.进行读操作
            while ((temp = bis.read(b)) != -1) {
                totalLen = totalLen + temp;
                bos.write(b, 0, temp);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4.关闭流
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("以字节缓冲流实现文件的拷贝:" + totalLen);
    }

    /**
     * 以字符缓冲流方式实现文件的拷贝
     *
     * @param src  源文件
     * @param dest 目标文件
     */
    private static void copyFile4(String src, String dest) {
        BufferedReader reader = null;
        BufferedWriter writer = null;
        // 1.使用File类
        File fa = new File(src);
        File fb = new File(dest);
        if (!fa.exists() || !fa.isFile()) {
            return;
        }
        if (fb.getParentFile() != null && !fb.getParentFile().exists()) {
            fb.getParentFile().mkdirs();
        }
        try {
            // 2.指定字节流
            reader = new BufferedReader(new FileReader(fa));
            writer = new BufferedWriter(new FileWriter(fb));
            char[] chars = new char[50];
            int i;
            // 3.进行读写操作
            while ((i = reader.read(chars)) != -1) {
                writer.write(chars, 0, i);
                writer.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4.关闭流
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("以字符缓冲流方式实现文件的拷贝");
    }
}

代码示例中虽然使用字符流进行文件拷贝,实际中推荐使用字节流进行文件拷贝,因为字符流对二进制字节文件拷贝会有问题。

5.小结

a.字节流的处理单位是字节,通常用来处理二进制文件,而字符流的处理单位是字符,通常用来处理文本文件。

b.不管是字节流还是字符流处理文件操作后,及时关闭打开的流。

c.推荐使用缓冲流对文件进行操作。

发布了142 篇原创文章 · 获赞 258 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/conconbenben/article/details/103434160