IO字节流,高效字节流BufferedInputStream/BufferedOutputStream,单级/多级文件夹的复制

本文是2020.5.24的课堂笔记,主要探讨了Java中的IO流,包括输入流和输出流的概念,重点讲解了FileOutputStream和FileInputStream的使用,以及如何进行文件复制。特别是BufferedInputStream和BufferedOutputStream的运用,展示了它们在提高文件读写效率上的优势。同时,文章还介绍了如何进行单级和多级文件夹的复制操作。

2020.5.24 课堂笔记

IO流

  1. 用来处理设备之间的数据传输。

  2. 分为:输入流和输出流

  3. 字节流:可以操作任意类型的文件(图片,音频等等)

    字符流:只能操作文本文件。

FileOutPutStream

  1. 创建一个文件输出流,来关联一个文件,当关联的文件不存在,就会创建文件。

  2. 往文件中写入数据:

    • write(int b):一次写入一个字节,如果超过字节范围,就会丢弃掉部分数据。

    • write(byte [] a):一次写入一个字节数组

    • write((byte [] a,int start,int length):一次写入字节数组的一部分

    • 怎么覆盖原文件,或者在源文件后面添加?在使用输出流构造方法时,

      FileOutputStream out = new FileOutputStream(“c.txt”,true);true在文件后面添加,否则覆盖。

package org.westos.demo0524.IO; 
 
/*Author:LH
CreatTime:2020.05.26.19:39*/

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test2 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream("b.txt");
//        每次将输出的数据添加到文档的尾部
        FileOutputStream out = new FileOutputStream("c.txt",true);
        byte[] bytes = new byte[1024 * 8];
        in.read(bytes);
        out.write(bytes);
//        要将换行符变成字节输入
        String s2="\r\n";
        byte[] bytes2 = s2.getBytes();
        in.read(bytes2);
        out.write(bytes2);
        String s="你是谁呀";
        byte[] bytes1 = s.getBytes();
        in.read(bytes1);
        out.write(bytes1);
        in.read(bytes2);
        out.write(bytes2);
        in.close();
        out.close();
    }
}
  1. 流使用完毕,要释放资源。close()方法。
    • 释放资源的原因:通知系统释放管理的文件资源。让IO流对象变成垃圾等待回收器回收
  2. 写入过程中:换行“\r\n”.注意将换行符变成字节数据

流的异常处理

  1. 异常不建议抛出去,而要自己处理,通过try …catch捕捉处理。
  2. 在异常处理中可以做一写逻辑,不仅是打印异常信息。

FileInputStream

  1. 概念:从文件中读取数据。如果读取不到有效的字节就会返回-1

  2. 输入流关联的文件不存在,就会报错。

  3. 构造方法和方法

    • 构造方法:

      FileInputStream(File file):创建一个输入流,传入一个File file。

      FileInputStream(String name):创建一个输入流,传入一个String name。

    • 方法:

      close():关闭文件输入流并释放资源

      read():文件的读入,从此输入流中读取一个数据字节。

      read(byte[] b):从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。

      read(byte[] b, int off, int len):从此输入流中将最多 len 个字节的数据读入一个 byte 数组中,其实位置从off开始。

  4. 流使用完毕,要释放资源。close()方法。

    • 注意:释放资源的位置和释放资源时的空指针异常

文件的复制

模板复制代码:

package org.westos.demo0524.IO;

import java.io.*;

/*Author:LH
CreatTime:2020.05.26.16:48*/
//复制文件
//步骤一:创建字节输入,输出流,输入输出流中封装要复制的文件的路径和名称
//步骤二:封装完,采用一次读取一个字节数组,这样会比较快。
//步骤三:创建字节数组,建议一次读取和写入8KB
//步骤四:将文件读入字节数组
//步骤五:将字节数组的字节,写入到文件中
//注意:建议自己捕捉和处理错误,输入输出对象关闭时,要判断是否为空
public class Test {
    public static void main(String[] args) {
        File file = new File("b.txt");
        File file1 = new File("c.txt");
        FileInputStream in = null;
        byte[] bytes = new byte[1024 * 8];
        try {
            in = new FileInputStream(file);
            in.read(bytes);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(file1);
            out.write(bytes);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
//            资源释放,放在finally里面,不管try有没有执行都会执行自己的语句
            try {
//            如果刚进去进捕捉到错误,没有创建输入,输出流就会空指针
//            此处就不用关闭,如果关闭就会报错--NullPointerException
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

BufferedInputStream/BufferedOutputStream

  1. 高效的输入输出流,它自身维护一个数组充当缓冲。字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,因此Java在设计时也考虑了这种方法,
  2. 所以提供了字节缓冲区流BufferedInputStream/BufferedOutputStream
  3. 字节缓冲区流自身维护了一个字节数组,因此编程者提供字节数组读写和一个字节读取速度差不多。

代码:字节流和高效字节流一次读取字节数组和一次读取一个字节的时间对比

package org.westos.demo0524.IO; 
 
/*Author:LH
CreatTime:2020.05.27.11:24*/

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//使用字节流读取视频文件
//一次读取一个字节
public class Test6 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream("C:\\Users\\LH\\Desktop\\b2.mp4");
        FileOutputStream out = new FileOutputStream("C:\\Users\\LH\\Desktop\\b4.mp4");
        int len=0;
        long time1 = System.currentTimeMillis();
        while ((len=in.read())!=-1){
           out.write(len);
       }
        long time2 = System.currentTimeMillis(); //耗时68591
        System.out.println(time2-time1);
        in.close();
        out.close();
    }
}
2.package org.westos.demo0524.IO; 
 
/*Author:LH
CreatTime:2020.05.27.10:26*/

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//使用字节IO流复制视频文件
public class Test3 {
    public static void main(String[] args) throws IOException {
        FileInputStream in = new FileInputStream("C:\\Users\\LH\\Desktop\\a1.mp4");
        FileOutputStream out = new FileOutputStream("C:\\Users\\LH\\Desktop\\a2.mp4");
        //一次读取一个8KB
        byte[] bytes = new byte[1024 * 8];
        int len = 0;
//返回当前时间的毫秒值
        long time1 = System.currentTimeMillis();
        while ((len = in.read(bytes)) != -1) {
            out.write(bytes, 0, len);
        }
        long time2 = System.currentTimeMillis(); //耗时37
        System.out.println(time2 - time1);
        in.close();
        out.close();
    }
}
3.package org.westos.demo0524.IO;

import java.io.*;

/*Author:LH
CreatTime:2020.05.27.10:42*/
//使用高效字节流复制视频
//一个字节一个字节复制
public class Test4 {
    public static void main(String[] args)throws IOException {
        BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\LH\\Desktop\\b2.mp4"));
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\Users\\LH\\Desktop\\b2副本.mp4"));
        long time1= System.currentTimeMillis();
        int read = 0;
        while ((read=in.read())!=-1){
            out.write(read);
        }
        long time2 = System.currentTimeMillis(); //耗时173
        System.out.println(time2-time1);
        in.close();
        out.close();
    }
}
4.package org.westos.demo0524.IO; 
 
/*Author:LH
CreatTime:2020.05.27.11:07*/
//使用高效字节流复制视频
//一次读取8KB
import java.io.*;

public class Test5 {
    public static void main(String[] args) throws IOException {
        BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\LH\\Desktop\\b2.mp4"));
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\Users\\LH\\Desktop\\b3副本.mp4"));
        byte[] bytes = new byte[1024 * 8];
        int len=0;
        long time1 = System.currentTimeMillis();
        while ((len=in.read(bytes))!=-1){
           out.write(bytes,0,len);
       }
        long time2 = System.currentTimeMillis(); //耗时34
        System.out.println(time2-time1);
        in.close();
        out.close();
    }
}

多级文件夹的复制
package org.westos.demo0524.IO; 
 
/*Author:LH
CreatTime:2020.05.27.22:36*/
import java.io.*;
//复制多级文件夹
//1.先将目标文件夹封装在File类中
//2.再将目的路径封装在File类中。并判断文件夹是否存在。不存在就创建一个
//3.获取创建完的路径。
//4.判断文件一级目录中是否含有文件夹,除文件夹的其他文本复制到封装好的目的路径中
//5.是文件夹的获取文件夹名字,将下一级路径封装在下级File类中,将文件夹的File类对象和下级路径的File类对象传到方法中,使用递归方法,继续分析复制文件。
public class MyTest3 {
    public static void main(String[] args) throws IOException {
//        封装目标文件夹
        File file = new File("G:\\kk");
//        封装目的路径。
        File file1 = new File("C:\\Users\\LH\\Desktop\\kk");
        copyFile(file, file1);
    }

    public static void copyFile(File f1, File f2) throws IOException {
//        判断目的路径下是否包含目标文件夹
        if (!f2.exists()) {
            f2.mkdirs();    //不包含就创建一个
        }
//        获取创建完成的目的文件夹的绝对路径。
        File absoluteFile = f2.getAbsoluteFile();
        File[] files = f1.listFiles();
//        判断文件夹中是否包含文件夹
        for (File file : files) {
            if (file.isDirectory()) {
//                是文件夹,就获取文件夹的名称
                String name = file.getName();
//                封装新的目的文件夹路径
                File newAbsoluteFile = new File(absoluteFile, name);
//                使用递归,继续分析下级文件夹
                copyFile(file, newAbsoluteFile);
            } else {
//                不是文件夹,就是用字节流赋值文件。
                String name = file.getName();
                File finalFile = new File(f2, name);
                byte[] bytes = new byte[1024 * 8];
                int len = 0;
                FileInputStream in = new FileInputStream(file);
                FileOutputStream out = new FileOutputStream(finalFile);
                while ((len = in.read(bytes)) != -1) {
                    out.write(bytes);
                }
//                最终赋值完毕,关闭资源。
                in.close();
                out.close();
            }
        }

    }
}
单级文件夹的复制
package org.westos.demo0526; 
 
/*Author:LH
CreatTime:2020.05.27.17:54*/

import java.io.*;

/*需求: 复制D:\\course这文件夹到E:\\course
        - 分析:
        - a: 封装D:\\course为一个File对象
        - b: 封装E:\\course为一个File对象,然后判断是否存在,如果不存在就是创建一个目录
        - c: 获取a中的File对应的路径下所有的文件对应的File数组
        - d: 遍历数组,获取每一个元素,进行复制
        - e: 释放资源*/
public class Test3 {
    public static void main(String[] args) throws IOException {
        File file = new File("G:\\javase");
        File file1 = new File("C:\\Users\\LH\\Desktop\\bb");
        boolean b = file1.exists();
        System.out.println("有没有文件夹:"+b);
        if (!b){
            boolean b1 = file1.mkdirs();
            System.out.println("创建成功与否:"+b1);
        }
        File[] name = file.listFiles();
        for (File file2 : name) {
            String name1 = file2.getName();
            File finalFile = new File(file1, name1);
            copyFile(file2,finalFile);
        }
    }
    public static void copyFile(File f1,File f2) throws IOException {
        BufferedReader in = new BufferedReader(new FileReader(f1));
        BufferedWriter out = new BufferedWriter(new FileWriter(f2));
        char[] chars = new char[1000];
        int len=0;
        while ((in.read(chars))!=-1){
            out.write(chars);
            out.flush();
        }
        out.close();
        in.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值