JavaDay13-字符集、FileReader、FileWriter

字符集&编码规则:

1、ASCII 英文字符集 8位
ASCII编码规则:补0
2、GB2312-->BIG5-->GBK 中文-->繁体-->中文+繁体
GBK编码规则:中文2字节存储,以1开头;英文1个字节,0开头
3、Unicode 世界上所有文字
UTF-8编码规则:中文3字节存储,以1110开头;英文1个字节,0开头
UTF-16编码规则:所有文字2字节存储
UTF-32编码规则:所有文字4字节存储

为什么会出现乱码?

1、在UTF-8中,中文是用3个字节来存储,读取时没有读取完整
2、解码时使用了不同的编码规则

如何防止出现乱码?

1、不要使用字节流读取文本文件,但可以拷贝
2、编码和解码使用同一种码表

编码&解码

public class EncodeDemo01 {
    public static void main(String[] args) {
        String str="ai你呦";
        byte[] bytes = str.getBytes();//getBytes()编码
        System.out.println(Arrays.toString(bytes));
        String str2=new String(bytes);//String的构造方法解码
        System.out.println(str2);
    }
}

字符流---字节流+字符集

  • 抽象类:
    Reader、Writer
  • 子类:
    FileReader、FileWriter

字符流原理解析:

  • 输入流
    1、创建字节对象-关联文件,并创建缓冲区(长度为8192字节的数组)
    2、读取数据-首先判断缓冲区中是否有数据可以读;然后从文件中获取数据,尽量装满缓冲区;从缓冲区中读取数据。
  • 输出流
    1、创建对象-如果没有开续写,会清空目的文件
    2、写入数据-将数据写入缓冲区中,缓冲区满了、调用flush方法、关流,上述三种方法都可以将缓冲器中的数据写入目的文件。

FileReader-空参read()

1、创建对象
2、读取字节
细节:定义变量接收
3、打印字符
细节:强制类型转换
4、释放资源

//FileReader-空参read()
public class CharStreamDemo01 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("E:\\...\\ioStreamPractise.txt");
        int ch;
        while((ch=fr.read())!=-1){//按字节读取,英文读取一个字节,中文读取3个字节(UTF-8),读取后转为十进制,赋值给ch
            System.out.println(ch);
            //System.out.print((char) ch);//将十进制数字转为字符-char()
        }
        fr.close();
    }
}

FileReader-read(char[] buffer)

1、创建对象
2、定义char[]
3、读取字符
细节:定义变量接收
4、打印字符
细节:强制类型转换、len
5、关闭资源

//FileReader-read(char[] buffer)
public class CharStreamDemo02 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("E:\\...\\ioStreamPractise.txt");
        char[] chars = new char[2];
        int len;
        while ((len=fr.read(chars))!=-1){
            //System.out.println(chars[0]);
            //System.out.println(chars[1]);
            System.out.print(new String(chars,0,len));
        }
        fr.close();
    }
}

FileWriter-write()

1、创建对象
细节:是否续写
2、调用write()
3、关闭资源

//FileWriter-write()
public class CharStreamDemo03 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("E:\\...\\ioStreamPractise.txt",true);
        //fw.write(36657);
        //fw.write("菊花残,满地伤,你的笑容已泛黄");
        char[] chars={'周', '杰', '伦'};
        fw.write(chars);
        fw.close();
    }
}

字节流vs字符流

1、字节流-可以拷贝任意文件
2、字符流-读取/写入纯文本文件

小练习-复制文件夹

  • 主函数
    1、创建源文件
    2、创建目的文件
    3、拷贝方法

  • 拷贝函数
    1、进入文件源
    2、遍历数组
    3、判断文件类型
    -文件:拷贝
    -输入流
    -输出流
    -拷贝(边读边写)
    -关流
    -文件夹:递归

  • 细节
    1、要考虑目的文件不存在的情况
    2、输出目的文件位置-new File(file2,file.getName())

  • 代码实现:

//复制文件夹
public class Demo01 {
    public static void main(String[] args) throws IOException {
        //1、文件源
        File file1 = new File("E:\\...\\src");
        //2、目的文件
        File file2 = new File("E:\\...\\dest");
        //3、拷贝
        copyFile(file1,file2);
    }

    private static void copyFile(File file1, File file2) throws IOException {
        file2.mkdirs();
        //递归
        //1、进入文件源
        File[] files = file1.listFiles();
        //2、遍历数组
        for (File file : files) {
            if(file.isFile()){
                //3、判断-文件-拷贝
                FileInputStream fis = new FileInputStream(file);
                FileOutputStream fos = new FileOutputStream(new File(file2,file.getName()));
                byte[] bytes = new byte[1024];
                int len;
                while((len=fis.read())!=-1){
                    fos.write(bytes,0,len);
                }
                fos.close();
                fis.close();
            }else{
                //4、判断-文件夹-递归
                copyFile(file,new File(file2,file.getName()));
            }
        }
    }
}
posted @ 2023-04-10 15:48  小园初来乍到  阅读(161)  评论(0)    收藏  举报