[java进阶]——IO流,递归实现多级文件拷贝

🌈键盘敲烂,年薪30万🌈

目录

一、认识IO流

二、了解编码与解码

二、IO流体系

三、字节输入输出流

四、字符输入输出流

五、多级文件拷贝


一、认识IO流

IO流也叫输入流(intput)、输出流(onput),该流就像java程序同硬盘之间的一条数据传输通道,我们说的输入流、输出流是向java程序输入数据、从java程序输出数据

二、了解编码与解码

我们知道存储在文件里面的都是二进制0 1,数据在往文件里存储前会先转为二进制,转化为了二进制再经过编码存储到文件里面。

假如我要存字符a,是如何编码的,a对应的ASCII码值为97,二进制为110 0001,补全8位比特位变为0110 0001,这就是a要存储的二进制,这也是英文字符的编码方案,那要是存储一个汉字呢,汉字也有对应的二进制的值,只不过这个表不是ASCII码表,而是GBK或者Unicode表,里面大约存储了2万多个汉字,2万多个汉字,我们用2个字节保存它的二进制戳戳有余,不同的标准有不同的编码方案,例如UTF-8编码方案一个汉字占3个字节,ANSI编码方案一个汉字占2个字节,我们要了解UTF-8编码方案。

UTF-8英文字符编码过程

UTF-8汉字编码过程

解析:

问题一有四个英文字符

问题二两个英文字符2个汉字字符
总结:

Unicode字符集利用UTF-8的编码方案

英文字符占一个字节且二进制第一位是0

中文字符占3个字节且每个字节二进制第一位是1
那你能不能解释一下为什么乱码呢???

原因一:编码与解码规则不一样

原因二:未读取完整个汉字字符

二、IO流体系

三、字节输入输出流

3.1输入流

适用范围: 可读取任何文件,一次性读取一个字节

如何使用: 1.获取文件字节流对象 2.read()方法 3.关闭流

代码解析:

构造方法里面可以是字符串,也可以是文件对象

read()方法有两个功能,读取一个字节并返回它ascii码值的十进制,移动指针

当读到文件末尾返回-1

最后close关闭流,不关闭该文件会被一直占用

java 复制代码
FileInputStream fis = new FileInputStream("10_16\\a.txt");
int tmp = 0;
while((tmp = fis.read()) != -1){
    System.out.print((char)tmp);
}
fis.close();

这样一个一个字节读取是不是太慢了啊,我们可以一次读取一个字节数组,这不就O了嘛

代码解析:

bytes用于保存每一次读取的数据,

read也是读取字节,移动指针,并且返回读取字节的个数。

注意:

每一次读取新数据会将原数据覆盖,所以如果最后一次没读够10字节,数组后面的内容是上一次读取的。

read()括号里面要穿入数组

bytes数组里的数据是字符,不是它ASCII码的十进制了

java 复制代码
FileInputStream fis = new FileInputStream("10_16\\a.txt");//路径要两个\\
byte[] bytes = new byte[10]; //一次性读取10个字节
int len= 0;
while((len= fis.read(bytes)) != -1){
    String s = new String(bytes, 0, len);
    System.out.print(s);
}
fis.close();

3.2输出流

代码解析:

构造函数的第二个参数表示你要不要续写该文件,如果是false,会清空源文件内容

不写默认为false

\r,\n代表回车换行符,如果只写一个,编译器会帮我们补全

write写入,最后别忘了关闭流

java 复制代码
        FileOutputStream fos = new FileOutputStream("10_16\\a.txt",false);
        fos.write(97); //写入字符a
        fos.write('a');
        fos.write('\r'); //写入回车换行符
        byte[] bytes = {97, 98, 99};
        fos.write(bytes);//写入字符a b c
        fos.close();

四、字符输入输出流

4.1输入流

只适用于读取纯文本文件(用记事本打开不会乱码),一次性读取一个字节或者一个字符

一个汉字如果采用UTF-8的编码方案,占3个字节,所以一次想读取一个有效字符,用文件字符流

代码分析:

跟上面一样,只不过要注意,读多个字符的时候,数组要用char类型

java 复制代码
        //一次读取一个有效字符
        FileReader fr = new FileReader("10_16\\a.txt");
        int tmp = 0;
        while ((tmp = fr.read()) != -1){
            System.out.print((char)tmp);
        }
        fr.close();
        //一次读取多个有效字符
        FileReader fr = new FileReader("10_16\\a.txt");
        int len = 0;
        char[] chars = new char[10];
        while ((len = fr.read(chars)) != -1){
            System.out.print(new String(chars, 0, len));
        }
        fr.close();

4.2输出流

可传入类型

java 复制代码
FileWriter fw = new FileWriter("10_16\\a.txt");
fw.write("hello world");
fw.close();

4.3字符流自带的加载缓冲区功能

利用字符流操作数据时,会在内存中开辟8192字节的缓冲区,每次读取或者写入数据都是先找缓冲区。

五、多级文件拷贝

核心思路:

创建两个文件路径src与dest,一个为要拷贝的文件,一个为拷贝的目的地

先创建改路径下的dest文件夹

遍历src文件,如果不是文件,继续递归,如果是文件,拷贝

java 复制代码
private static void copyFile1(File src, File dest) throws IOException {
        //先创建文件夹
        dest.mkdir();
        //进入路径  遍历文件
        for (File file : src.listFiles()) {
            if(file.isDirectory()){
                //递归
                //这里的dest路径要好好想一下
                copyFile1(file, new File(src, file.getName()));
            }else{
                //拷贝文件
                FileInputStream fis = new FileInputStream(src);
                FileOutputStream fos = new FileOutputStream(dest);
                int tmp = 0;
                while ((tmp = fis.read()) != -1){
                    fos.write(tmp);
                }
                //关闭流
                fos.close();
                fis.close();
            }
        }

六、总结

操作纯文本文件可以用字符和字节流,不是纯文本文件用字节流

字节输入流以字节为单位向java程序传输数据,可以是1个字节,可以是1个字节数组,字符输入流以字符为单位也可以是一个字符或一个字符数组,输出流与之类似

字符流有缓冲区的概念

相关推荐
菜鸟起航ing15 分钟前
【Java面试系列】Spring Boot微服务架构下的分布式事务解决方案与性能优化详解 - 3-5年Java开发必备知识
java·spring boot·微服务·性能优化·分布式事务
小薛博客25 分钟前
架构设计之Redisson分布式锁-可重入同步锁(一)
java·redis·分布式
小开不是小可爱33 分钟前
leetcode_454. 四数相加 II_java
java·数据结构·算法·leetcode
Koma-forever34 分钟前
java设计模式-原型模式
java·设计模式·原型模式
zheshiyangyang39 分钟前
JavaScript---原型和原型链
开发语言·前端·javascript
pumpkin8451444 分钟前
理解 Rust 中的 String 分配机制
开发语言·rust
小宁学技术1 小时前
MATLAB在工程领域的实际应用案例
开发语言·matlab·matlab实际应用案例·matlab应用案例·matlab 实际应用案例
magic 2451 小时前
MyBatis的缓存、逆向工程、使用PageHelper、使用PageHelper
java·spring·maven·mybatis
XiaoLeisj2 小时前
【图书管理系统】深入解析基于 MyBatis 数据持久化操作:全栈开发图书管理系统:查询图书属性接口(注解实现)、修改图书属性接口(XML 实现)
xml·java·数据库·spring boot·sql·java-ee·mybatis
癞皮狗不赖皮2 小时前
WEB攻防-Java安全&JNDI&RMI&LDAP&五大不安全组件&RCE执行&不出网&不回显
java·jndi注入·rce代码执行