Java基础进阶_day11_(IO,字符流,递归)

Java基础进阶_day11_(IO,字符流,递归)

1. 字符流

字符流的本质是:字符流=字节流+编码表.
编码表:由字符及其对应的数值组成的一张表.

# 字符串编码:
    构造方法:public String(byte[] bytes,String charsetName):使用指定的字符集解码字节数组;
    成员方法:public byte[] getBytes(String charsetName):使用指定的字符集编码字符串.
# 编码:将字符解析为字节数据,String --> byte[]
# 解码:将字节数据解析为字符串,byte[] --> String
# 注意事项:编解码的规则要一致.
  • 字符流:是在字节流的基础之上添加了编码表,字符流也称为转换流(不同编码规则间的转换)
    • 字符输入流:Reader抽象类是所有字符输入流的根类;
    • 字符输出流:Writer抽象类是所有字符输出流的根类.
    • 字符输出流写数据是先将数据写到缓冲区,需要使用flush方法将数据刷新到文件.
    • 复制文件时,一般使用字节流,不使用字符流(先将读取的字节转换为字符,再将字符转换为字节写出),单独读取文件或写出文件时使用字符流.字符流只能赋值纯文本文件,复制图片等其他格式会出现文件损坏.

2. OutputStreamWriter类

OutputStreamWriter类:是字符输出流Writer的实现类,是在字节输出流OutputStream的基础上增加字符编码.

2.1 构造方法

public OutputStreamWriter(OutputStream out):创建使用默认字符编码(依据平台)的字符输出流对象;
public OutputStreamWriter(OutputStream out, String charsetName):创建使用指定字符编码的字符输出流对象;

2.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):一次写一个字符串的一部分.

3. InputStreamReader类

InputStreamReader类:字符输入流Reader的实现类,是在字节输入流InputStream的基础上增加字符编码.

3.1 构造方法

public InputStreamReader(InputStream in):创建使用默认字符编码的字符输入流对象;
public InputStreamReader(InputStream in,String charsetName):创建使用指定字符编码的字符输入流对象;

3.2 成员方法

public int read():一次读取一个字符,没有则返回-1;
public int read(char[] chs):一次读取一个字符数组返回是每次实际读取的字符长度,没有数据返回-1.

4. 字符流便捷类

# 字符流的便捷类:由于大多数的IO操作均是在本地实现,则字符流提供了使用默认编码的子类作为便捷类使用.

4.1 FileWriter类

FileWriter类:是字符输出流OutputStreamWriter类便捷类,也是其子类.其成员方法方法和父类完全相同.

4.1.1 构造方法
FileWriter(String FileName):传递一个文件名;
FileWriter(String FileName,boolean append):参数是一个文件名,并设置是否是追加写数据的方式,append为true时,追加方式,默认是false.
4.1.2 成员方法
void write(String str):写一个字符串
void write(String str,int index,int len):写字符串中部分数据
    注意:其中的index不能索引越界,len也不能超过可以截取的字符串的长度
void write(int ch):写一个字符数据,可以使用字符'A',也可以是字符对应的ASCII值
void wirte(char[] chs):写一个字符数组
void write(char[] chs,int index,int len):写一个字符数组的一部分
   注意:其中的index不能索引越界,len也不能超过可以截取的字符串的长度
flush():刷新内存缓冲区,将要写入的字符串写入到文件;可以继续使用流对象写数据
close():
    a.关闭输出流,先缓冲区的数据flush方法,
    b.然后通知系统释放和该文件相关的系统资源
    c.流对象关闭后,不能再继续使用(不能再写数据到文件)
close和flush方式将数据写入文件的区别:
    前者是关闭了流对象,后续无法再向文件中写数据
    后者只是将缓冲区中数据写到文件,还可以再向文件写数据,然后再执行此方法将数据写到文件.

4.2 FileReader类

FileReader类:是字符输入流InputStreamReader类的便捷类,也是其子类,成员方法和父类完全相同.

4.2.1 构造方法
FileReader(String filename):filename不能为空,否则会报异常.
4.2.2 成员方法
int read():一次读取一个字符,读完当前字符后,下次就读取下一个字符,没有数据时返回-1,读取字符时需要将结果强制类型转换为char类型,否则显示的是字符对应的值;
int read(char[] chs):一次读取一个字符数组,读完当前字符后,下次就读取下一个字符,没有数据时返回-1,返回的是每次实际读取的字符的个数;
注意事项:如果要读取的文件不存在,这会报错,系统找不到指定文件

5. 字符缓冲流

字符缓冲流:是在基本的字符流的基础上增加缓冲区.

5.1 BufferedWriter类

# BufferedWriter:将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入.
    是在FileWriter类的基础上加强功能,因此创建本类的对象需要FileWriter的实例对象作为参数.
5.1.1 构造方法
public BufferedWriter(Writer out)创建一个使用默认大小输出缓冲区的缓冲字符输出流.
5.1.2 成员方法(特殊方法)
void newLine():写一个换行符,由系统决定是那个换行符

5.2 BufferedReader类

# BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取.
    是在FileReader类的基础上加强功能,因此创建本类的对象需要FileReader的实例对象作为参数.
5.2.1 构造方法
public BufferedReader(Reader in)创建一个使用默认大小输入缓冲区的缓冲字符输入流.
5.2.2 成员方法(特殊方法)
String readLine():一次读一行数据,但是不读取换行符,没有数据时返回null

6. 字符流案例

public class MyIODemo03 {
    public static void main(String[] args) throws IOException {
        // 字符输入流和输出流测试,文件复制
        test01();
        // 字符输入流和输出流的便捷类测试,文件复制
        test02();
        // 字符缓冲流复制文件
        test03();
    }
    public static void test03() throws IOException, FileNotFoundException {
        // 创建输入输出缓冲流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("java2.java"));
        BufferedReader br = new BufferedReader(new FileReader("java1.java"));
        // 赋值文本
        /*int ch;
        while((ch=br.read())!=-1) {
            // 将文本写入文件
            bw.write(ch);
        }*/
        // 赋值文本
        String line;
        // 每次读取一行数据
        while((line=br.readLine()) != null) {
            // 每次写一个字符串
            bw.write(line);
            // 写完一行要写一个换行
            bw.newLine();
            // 刷新数据到文件
            bw.flush();
        }
        // 释放资源
        bw.close();
        br.close();
    }
    public static void test02() throws IOException {
        // 创建输入输出流对象
        FileReader fr = new FileReader("java.java");
        FileWriter fw = new FileWriter("java1.java");
        // 复制文件
        char[] chs = new char[1024]; // 数组的长度一般是1024及其整数倍
        int len = 0; // 每次实际读取的字符的个数
        // 读取数据,当数据读取完毕,会返回-1
        /*while((len = fr.read(chs)) != -1) {
            // 每次读取几个字符,就从字符数组中取出几个字符
            System.out.println(new String(chs,0,len));
        }*/
        // 赋值文本
        while((len = fr.read(chs)) != -1) {
            // 赋值文本,将本次实际读取的字符个数,复制到文本文件
            fw.write(chs, 0, len);
        }
        // 刷新缓冲区,将数据写入到文件,可以不写此方法,
        // 后面的close方法释放系统资源时会将缓冲区中数据写入到文件
        // fw.flush();
        // 释放资源
        fw.close();
        fr.close();
    }
    public static void test01() throws FileNotFoundException, IOException {
        // 字符输入流和输出流测试,文件复制
        InputStreamReader isr = new InputStreamReader(new FileInputStream("Demo.java"));
        OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream("Demo2.txt"));
        // 复制文件,方式1
        /*int by;
        while((by = isr.read()) != -1) {
            osr.write(by);
        }*/
        // 复制文件,方式2
        char[] chs = new char[1024];
        int len;
        while((len = isr.read(chs)) != -1) {
            osr.write(chs, 0, len);
            osr.flush();
        }
        // 释放资源
        isr.close();
        osr.close();
    }
}

7. 递归

递归:方法定义中调用方法本身的现象

注意事项

# A:要有出口,否则就是死递归;
# B:次数不能太多,否则就内存溢出;
# C:构造方法不能递归使用.

案例

public class MyDiGuiDemo {
    public static void main(String[] args) {
        // 递归获取指定文件夹下所有的以.java结尾的文件
        File file = new File("E:\\develop");
        // 调用递归 方法
        getAllFiles(file);
    }
    /*
     * 输出指定目录下的所有符合条件的文件
     */
    public static void getAllFiles(File file) {
        if(file.isDirectory()) {
            File[] listFiles = file.listFiles();
            for (File file2 : listFiles) {
                if(file2.isDirectory()) {
                    getAllFiles(file2);
                } else {
                    if(file2.getName().endsWith(".java")) {
                        System.out.println(file2.getAbsolutePath());
                    }
                }
            }
        }else {
            if(file.getName().endsWith(".java")) {
                System.out.println(file.getAbsolutePath());
            }
        }
    }
}

8. IO流小结

8.1 IO流小结

IO流总结

8.2 字节流和字符流注意事项

# 字节流可以是复制任意格式的文件;
# 字节流复制中文(占2个字节)输出时会出现显示半个中文的情况;
# 字符流只能赋值纯文本文件格式的文件,不能复制和读取图片和视频等其他非纯文本的文件,因为字符流复制读取会将每次读取到的2个字节转换为字符(当读取的2个字节组合在码表中不存在时,系统会给出?代替),输出写数据时是将1个字符根据码表转换为2个字节,当遇到?时,由于不知道?代表的字符,则转换后的2个字节和读取的有误差,导致文件损坏.

8.3 IO流复制文本文件的9中方式

/*
 * 9种复制文件的方式
 */
public class MyIOTest05 {
    public static void main(String[] args) throws IOException {
        String srcFile = "a.txt";
        String desFile = "b1.txt";
        /**
         * 字节流复制文件
         */
        method01(srcFile, desFile);
        method02(srcFile, desFile);
        method03(srcFile, desFile);
        method04(srcFile, desFile);
        /**
         * 字符流复制文件
         */
        method05(srcFile, desFile);
        method06(srcFile, desFile);
        method07(srcFile, desFile);
        method08(srcFile, desFile);
        method09(srcFile, desFile);
    }
    public static void method09(String srcFile, String desFile)
            throws FileNotFoundException, IOException {
        BufferedReader br = new BufferedReader(new FileReader(srcFile));
        BufferedWriter bw = new BufferedWriter(new FileWriter(desFile));
        String line = null;
        while((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
        }
        bw.close();
        br.close();
    }
    public static void method08(String srcFile, String desFile)
            throws FileNotFoundException, IOException {
        BufferedReader br = new BufferedReader(new FileReader(srcFile));
        BufferedWriter bw = new BufferedWriter(new FileWriter(desFile));
        char[] chs = new char[1024];
        int len = 0;
        while((len = br.read(chs)) != -1) {
            bw.write(chs, 0, len);
        }
        bw.close();
        br.close();
    }
    public static void method07(String srcFile, String desFile)
            throws FileNotFoundException, IOException {
        BufferedReader br = new BufferedReader(new FileReader(srcFile));
        BufferedWriter bw = new BufferedWriter(new FileWriter(desFile));
        int ch = 0;
        while((ch = br.read()) != -1) {
            bw.write(ch);
        }
        bw.close();
        br.close();
    }
    public static void method06(String srcFile, String desFile)
            throws FileNotFoundException, IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream(srcFile));
        OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream(desFile));

        char[] chs = new char[1024];
        int len = 0;
        while((len = isr.read(chs)) != -1) {
            osr.write(chs, 0, len);
        }
        osr.close();
        isr.close();
    }
    public static void method05(String srcFile, String desFile)
            throws FileNotFoundException, IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream(srcFile));
        OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream(desFile));

        int ch = 0;
        while((ch = isr.read()) != -1) {
            osr.write(ch);
        }
        osr.close();
        isr.close();
    }
    public static void method04(String srcFile, String desFile)
            throws FileNotFoundException, IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desFile));

        byte[] bys = new byte[1024];
        int len = 0;
        while((len = bis.read(bys)) != -1) {
            bos.write(bys, 0, len);
        }
        bos.close();
        bis.close();
    }
    public static void method03(String srcFile, String desFile)
            throws FileNotFoundException, IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desFile));
        int by = 0;
        while((by = bis.read()) != -1) {
            bos.write(by);
        }
        bos.close();
        bis.close();
    }
    public static void method02(String srcFile, String desFile)
            throws FileNotFoundException, IOException {
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(desFile);
        byte[] bys = new byte[1024];
        int len = 0;
        while((len = fis.read(bys)) != -1) {
            fos.write(bys, 0, len);
        }
        fos.close();
        fis.close();
    }
    public static void method01(String srcFile, String desFile)
            throws FileNotFoundException, IOException {
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(desFile);
        int by = 0;
        while((by = fis.read()) != -1) {
            fos.write(by);
        }
        fos.close();
        fis.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值