Day13-Java进阶-IO字节流&字符流及其练习题

1. IO流介绍

2. IO 流体系结构

字节流读取纯文本文件会出现乱码问题

2.1 FileOutputStream 字节输出流

package com.itheima.stream.output;

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

public class FileOutputStreamDemo3 {
    /*
        IO流的异常处理方式: jdk7版本之前
     */
    public static void main(String[] args) {

        FileOutputStream fos = null;

        try {
            fos = new FileOutputStream("D:\\B.txt");
            fos.write("abc".getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2.2 FileInputStream 字节输入流

package com.itheima.stream.input;

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

public class FileInputStreamDemo1 {
    /*
        字节流读取数据

            public int read() : 读取单个字节
     */
    public static void main(String[] args) throws IOException {

        FileInputStream fis = new FileInputStream("D:\\A.txt");

        int i;
        while ((i = fis.read()) != -1) {
            System.out.println((char) i);
        }

        fis.close();

    }
}

package com.itheima.stream.input;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;

public class FileInputStreamDemo2 {
    /*
        字节流读取数据

            public int read(byte[] bys) : 读取一个字节数组

                    - 将读取到的字节, 存入数组容器, 返回读取到的有效字节个数
     */
    public static void main(String[] args) throws IOException {

        FileInputStream fis = new FileInputStream("D:\\A.txt");

        // 准备菜篮子, 用于装(字节)
        byte[] bys = new byte[2];

        int len;
        while( (len = fis.read(bys)) != -1 ){
            String s = new String(bys, 0, len);
            System.out.print(s);
        }

        fis.close();

    }
}

2.3 综合案例

package com.itheima.stream;

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

public class CopyTest1 {
    /*
        将 D:\嘿嘿.png,拷贝到 E:\ 根目录下

        分析:
                1. 创建输入流对象读取文件
                2. 创建输出流对象关联数据目的
                3. 读写操作
                4. 关流释放资源
     */
    public static void main(String[] args) throws IOException {
/*        // 1. 创建输入流对象读取文件
        FileInputStream fis = new FileInputStream("D:\\猫咪.jpg");
        // 2. 创建输出流对象关联数据目的
        FileOutputStream fos = new FileOutputStream("E:\\猫咪.jpg");
        // 3. 读写操作
        byte[] bys = new byte[1024];
        int len;
        while( (len = fis.read(bys)) != -1){
            fos.write(bys, 0, len);
        }
        // 4. 关流释放资源
        fis.close();
        fos.close();*/

        // 1. 创建输入流对象读取文件
        FileInputStream fis = new FileInputStream("D:\\猫咪.jpg");

        // 2. 创建输出流对象关联数据目的
        FileOutputStream fos = new FileOutputStream("D:\\test\\猫咪.jpg");

        // 3. 读写操作
        byte[] bytes = new byte[1024];
        int len;
        while((len = fis.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }

        // 4. 关流释放资源
        fis.close();
        fos.close();
    }
}

3. 字节缓冲流-(时间问题~暂时省略~)

4. 字符流介绍

4.1 FileReader 字符输入流

package com.itheima.stream.character.reader;

import java.io.FileReader;
import java.io.IOException;

public class FileReaderDemo1 {
    /*
        FileReader: 用于读取纯文本文件,解决中文乱码问题

            构造方法:
                    1. public FileReader(String fileName) 字符输入流关联文件,路径以字符串形式给出
                    2. public FileReader(File file) 字符输入流关联文件,路径以File对象形式给出

            成员方法:
                    public int read() : 读取单个字符
                    public int read(char[] cbuf) : 读取一个字符数组, 返回读取到的有效字符个数
     */
    public static void main(String[] args) throws IOException {

        FileReader fr = new FileReader("D:\\A.txt");

        char[] chs = new char[1024];

        int len;
        // 读取多个字符
        while( (len = fr.read(chs)) != -1 ){
            String s = new String(chs, 0, len);
            System.out.println(s);
        }

        fr.close();

    }

    /**
     * 读取单个字符
     */
    private static void method() throws IOException {
        FileReader fr = new FileReader("D:\\A.txt");

        int i;
        while ((i = fr.read()) != -1) {
            System.out.print((char)i);
        }

        fr.close();
    }
}

4.2 字符集与字符编码

package com.itheima.stream.character;

import java.io.IOException;
import java.util.Arrays;

public class StringDemo {
    /*

        平台默认字符编码 : Unicode - UTF-8的形式

        重点记忆: 中文字符, 通常都是由负数的字节进行组成的.
                    特殊情况: 可能会出现正数, 但是就算有正数, 第一个字节肯定是负数

        注意事项: 今后如果出现乱码问题, 大概率是因为编解码方式不一致所导致的.

        编码: 字符转字节
                public byte[] getBytes() : 使用平台默认字符编码方式, 对字符串编码
                public byte[] getBytes(String charsetName) : 使用使用字符编码方式, 对字符串编码

        解码: 字节转字符
                public String(byte[] bytes) : 使用平台默认字符编码方式, 对字符串解码
                public String(byte[] bytes, String charsetName) : 使用使用字符编码方式, 对字符串解码

     */
    public static void main(String[] args) throws IOException {
        String s = "你好,你好";
        byte[] bytes = s.getBytes();
        System.out.println(Arrays.toString(bytes));

        byte[] gbks = s.getBytes("gbk");
        System.out.println(Arrays.toString(gbks));

        System.out.println("----------------------------");

        byte[] utf8Bytes = {-28, -67, -96, -27, -91, -67, 44, -28, -67, -96, -27, -91, -67};
        byte[] gbkBytes = {-60, -29, -70, -61, 44, -60, -29, -70, -61};

        String s1 = new String(gbkBytes, "GBK");
        System.out.println(s1);
    }
}

4.3 FileWriter 字符输出流

package com.itheima.stream.character.writer;

import java.io.FileWriter;
import java.io.IOException;

public class FileWriterDemo1 {
    /*
        FileWriter字符输出流写出数据 :

        构造方法:
                FileWriter(String fileName):                         字符输出流关联文件,路径以字符串形式给出
                FileWriter(String fileName, boolean append):         参数2: 追加写入的开关
                FileWriter(File file):                               字符输出流关联文件,路径以File对象形式给出
                FileWriter(File file, boolean append):               参数2: 追加写入的开关

        成员方法:
                public void write(int c)                             写出单个字符
                public void write(char[] cbuf)                       写出一个字符数组
                public void write(char[] cbuf, int off, int len)     写出字符数组的一部分
                public void write(String str)                        写出字符串
                public void write(String str, int off, int len)      写出字符串的一部分
     */
    public static void main(String[] args) throws IOException {

        FileWriter fw = new FileWriter("D:\\C.txt");

        char[] chs = {'a','b','c'};

        fw.write('a');
        fw.write(chs);
        fw.write(chs, 0, 2);
        fw.write("你好你好~");
        fw.write("哈哈哈哈哈", 0, 2);

        fw.close();


    }
}

package com.itheima.stream.character.writer;

import java.io.FileWriter;
import java.io.IOException;

public class FileWriterDemo2 {
    /*
        注意事项: 字符输出流写出数据, 需要调用flush或close方法, 数据才会写出

            flush() : 刷出数据, 刷出后可以继续写出
            close() : 关闭流释放资源, 顺便刷出数据, 关闭后不可以继续写出
     */
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:\\D.txt");
        fw.write("人活一世, 草木一秋");
        fw.write("\r\n");
        fw.write("今晚不减肥, 我要吃肉!");
        fw.close();
    }
}

5. IO 流-练习题

5.1 案例1-图片文件加解密

package com.itheima.stream;

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

public class ImageTest {
    /*
        图片文件加密解密

            加密思路:改变原始文件中的字节,就无法打开了
                    字节 ^ 2
            解密思路:将文件中的字节还原成原始字节即可
                    字节 ^ 2

     */
    public static void main(String[] args) throws IOException {

        // 1. 创建字节输入流对象, 关联要加密的图片
        FileInputStream fis = new FileInputStream("D:\\A.jpg");

        // 2. 创建一个集合容器, 用于存取读到的字节(为便于不用考虑容器长度大小, 使用集合)
        ArrayList<Integer> list = new ArrayList<>();

        // 3. 循环读取文件的字节, 并存入集合
        int i;
        while((i = fis.read()) != -1){
            list.add(i);
        }

        // 4. 关闭输入流
        fis.close();

        // 5. 创建字节输出流对象, 关联图片文件
        FileOutputStream fos = new FileOutputStream("D:\\A.jpg");

        // 6. 遍历集合, 从集合中取出字节, 并写入
        for (Integer myByte : list) {
            fos.write(myByte ^ 2);
        }

        // 7. 关闭输出流
        fos.close();
    }
}

5.2 案例2-统计字符次数

package com.itheima.stream;

import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.function.BiConsumer;

public class CharacterTest {
    /*
        统计文件中每一个字符出现的次数,随后展示在控制台

        效果:
        A(1)B(2)C(3)
     */
    public static void main(String[] args) throws IOException {
        // 1. 准备map集合, 用于统计每个字符出现的次数
        HashMap<Character, Integer> hm = new HashMap<>();

        // 2. 创建字符输入流读取纯文本文件
        FileReader fr = new FileReader("D:\\info.txt");

        // 3. 将每个字符存入集合
        int i;
        while ((i = fr.read()) != -1){
            char c = (char) i;
            // 4. 统计每个字符出现的个数
            if (!hm.containsKey(c)){
                hm.put(c, 1);
            } else {
                hm.put(c, hm.get(c) + 1);
            }
        }

        // 5. 关闭输入流
        fr.close();

        // 6. 准备StringBuild对字符进行拼接操作
        StringBuilder sb = new StringBuilder();
        hm.forEach(new BiConsumer<Character, Integer>() {
            @Override
            public void accept(Character key, Integer value) {
                sb.append(key).append("(").append(value).append(")");
            }
        });

        System.out.println(sb);
    }
}

5.3-案例3-文件夹拷贝

package com.itheima.stream;

import java.io.*;

public class CopyDirTest {
    /*
        拷贝一个文件夹, 考虑子文件夹

        将D:\\test文件夹, 拷贝到E:\\
     */
    public static void main(String[] args) throws IOException {
        File src = new File("D:\\test");
        File dest = new File("E:\\");

        if (src.equals(dest)) {
            System.out.println("目标文件夹是源文件夹的子文件夹");
        } else {
            copyDir(src, dest);
        }


    }

    public static void copyDir(File src, File dest) throws IOException {

        File newDir = new File(dest, src.getName());
        newDir.mkdirs();

        // 从数据源中获取数据(File对象)
        File[] files = src.listFiles();
        // 遍历数组, 获取每一个文件或文件夹对象
        for (File file : files) {
            // 判断当前对象是否是文件
            if (file.isFile()) {
                // 是的话直接拷贝
                FileInputStream fis = new FileInputStream(file);
                FileOutputStream fos = new FileOutputStream(new File(newDir, file.getName()));

                int len;
                byte[] bys = new byte[1024];
                while ((len = fis.read(bys)) != -1) {
                    fos.write(bys, 0, len);
                }

                fis.close();
                fos.close();

            } else {
                // 如果是文件夹, 递归调用方法
                copyDir(file, newDir);
            }
        }
    }
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码里码理~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值