[API]缓冲字符流&IO总结&异常(八)

缓冲字符流:BufferedWriter/PrintWriter和BufferedReader

  • 内部也有一个缓冲区,读写文本数据以块读写形式加快效率

  • 缓冲字符流有一个特别的功能:可以按行读写文本数据。

  • PrintWriter具有自动行刷新的缓冲字符输出流,实际开发中更常用,它内部总是会自动连接BufferedWriter作为块写加速使用。

package io;
import java.io.*;
import java.nio.charset.StandardCharsets;

/*
缓冲字符流-------最常用的读写字符串的流
是一对高级流,并且是字符流
内部维护一个默认8KB(8192)长度的char数组,还是以块读写形式读写字符以提高读写效率
BuffredWriter和BufferedReader

PrintWriter:按行写入数据
 */
public class PWDemo {
    public static void main(String[] args) throws IOException {
        //最常用写入字符串方式:
        //底层连接了BufferedWriter,连接了OutputStreamWriter,连接了FileOutputStream
        PrintWriter pw = new PrintWriter("pw.txt");
        pw.println("和我在成都的街头走一走,哦哦哦哦..");
        pw.println("直到所有的灯都熄灭了也不停留");
        System.out.println("写出完毕");
        pw.close();

        /*
        FileOutputStream fos = new FileOutputStream("pw.txt"); //文件流(低级流)
        OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8); //转换流(高级流)
        BufferedWriter bw = new BufferedWriter(osw); //缓冲字符流(高级流)
        bw.write("和我在成都的街头走一走,哦哦哦哦..");
        bw.write("直到所有的灯都熄灭了也不停留");
        System.out.println("写出完毕!");
        bw.close(); //先调用flush()冲水
         */
    }
}

package io;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 *
 */
public class PWDemo2 {
    public static void main(String[] args) throws FileNotFoundException {
        //文件流(字节流,低级流):将字节写入到文件中
        FileOutputStream fos = new FileOutputStream("pw.txt");
        //转换流(字符流,高级流):1.负责衔接字符流与字节流  2.将写出的字符转换为字节再写出
        OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
        //缓冲字符流(字符流,高级流):块文本数据加速(内部缓冲区默认8192个char)
        BufferedWriter bw = new BufferedWriter(osw);
        //PrintWriter(字符流,高级流): 1.按行写出字符串  2.具有自动行刷新功能
        //构造器第1个参数为流,第2个参数可以传入boolean类型的数据来表示是否打开自动刷新功能(flush)
        PrintWriter pw = new PrintWriter(bw,true);

        Scanner scan = new Scanner(System.in);
        System.out.println("请开始输入内容,单独输入exit时退出");
        while(true){
            String line = scan.nextLine();
            if("exit".equals(line)){
                break;
            }
            //当开启自动行刷新后,每当调用println()方法写出一行后都会自动flush()
            //注意:print()不会flush的
            pw.println(line);
        }
        pw.close();
    }
}

package io;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * 缓冲字符输入流读取文本数据
 */
public class BRDemo {
    public static void main(String[] args) throws IOException {
        //文件流(字节流,低级流)
        FileInputStream fis = new FileInputStream("pw.txt");
        //转换流(字符流,高级流)
        InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
        //缓冲字符流(字符流,高级流)
        BufferedReader br = new BufferedReader(isr);
        /*
          String readLine():
          读取一行字符串,返回的字符串中不包含最后的换行符
          如果单独读取到了换行符(一个空行)则返回值为空字符串("")
          如果返回值为null,则表示读到了末尾
         */
        String line;
        while((line=br.readLine())!=null){
            System.out.println(line); //换行输出
            //System.out.print(line); //没有换行操作
        }
        br.close();

    }
}

IO总结:

  • 文件流:低级流/节点流,字节流--------------FileInputStream和FileOutputStream

    • 作用:实际连接程序与文件的"管道",读写字节(单字节读写、块读写)

  • 缓冲字节流:高级流/处理流,字节流--------BufferedInputStream和BufferedOutputStream

    • 作用:块读写字节数据加速

  • 对象流:高级流/处理流,字节流---------------ObjectInputStream和ObjectOutputStream

    • 作用:对象序列化和反序列化

  • 转换流:高级流/处理流,字符流---------------InputStreamReader和OutputStreamWriter

    • 作用:衔接字符流与字节流、将字符转换为字节

  • 缓冲字符流:高级流/处理流,字符流---------BufferedReader和BufferedWriter/PrintWriter

    • 作用:块读写文本字符数据加速、按行读写字符串(PrintWriter具有自动行刷新功能)

流的选择:读写java对象就用对象流,想读写字符串就是缓冲字符流

 异常:

  • java.lang.Throwable是所有异常的顶级超类,它的下面派生了两个子类型:

    • Error:错误,表示系统级别错误,是不可恢复的错误,比如说:虚拟机内存溢出等,Error通过异常处理机制是处理不了的。

    • Exception:异常/意外,表示程序级别的异常,是可以通过异常处理机制恢复的错误,下面有多个派生类表达不同的异常类型

异常处理机制解决的问题:

  • 正常程序能走完,但因为某些特殊原因(网络问题、突发情况)导致程序无法正常走完,属于意外情况,通过程序逻辑(分支/循环)是无法解决了,这时才需要使用异常处理机制来做个B计划。直白的说:你明知道会发生,但是还没办法通过逻辑来处理的问题,才需要异常处理机制帮助解决。

    异常追责过程:

    1. 当发生错误时,JVM会new一个异常出来,要求代码必须解决。

    2. 若代码中没有做异常处理,则找到代码所在的方法来处理

    3. 若代码所在的方法也没有处理,会继续往上追方法,直到追到main方法

    4. 若main方法也没有处理,则继续找到调用main方法的JVM,最后程序直接终止

异常处理机制:

try...catch:若try中代码出现异常,将会被catch捕获,若catch没有捕获住,则程序依然被杀死

package exception;

/**
 * java异常处理机制: try...catch
 * try{
 *     代码片段
 * }catch(XXXException e){
 *     当try的代码片段出现XXXException时的补救措施
 * }
 */
public class TryCatchDemo {
    public static void main(String[] args) {
        System.out.println("程序开始了...");

        try{
            /*
              try块中某句代码如果出现了异常,那么try块中这句代码以下的代码都不执行了
              try语句中如果不出现异常,catch块不执行
             */
            String line = null;
            System.out.println(line.length());
            String line1 = ""; //因为上一句发生了异常,所以try块中此句及以下代码都不会被执行了
            System.out.println(line1.charAt(0));
            String line2 = "abc";
            System.out.println(Integer.parseInt(line2));
        }catch(NullPointerException e){ //捕获空指针异常
           System.out.println("出现了空指针异常并解决了"); //处理办法
        }catch(StringIndexOutOfBoundsException e){ //捕获字符串下标越界异常
           System.out.println("出现了字符串下标越界异常并解决了"); //处理办法
        //}catch(NullPointerException | StringIndexOutOfBoundsException e){ //若多个异常具有相同处理方式时,可以合并到一个catch中进行处理
        //   System.out.println("出现空指针或字符串下标越界异常并解决了");
        }catch(Exception e){ //可以在最后捕获超类型异常,凡是该异常的子类型都可以被捕获并处理
            System.out.println("反正就是出了个错并解决了");
        }

        System.out.println("程序结束了...");
    }
}

 

finally:是异常处理机制中的最后一块,不能独立存在,它可以跟着try后(try...finally),或最后一个catch后(try...catch...finally)。

注意:

  1. finally可以保证无论try块中是否出现异常,最后finally都必定执行。通常用来做释放资源这类操作。

  2. JDK7之后,java提供了一个新特性:自动关闭特性。旨在IO操作中可以更简洁的使用异常处理机制完成最后的close操作。只有实现了AutoCloseable接口的类才能写在try()中,注意:所有流都实现了AutoCloseable接口。

package exception;

/**
 * finally块的演示
 */
public class FinallyDemo {
    public static void main(String[] args) {
        System.out.println("程序开始了...");

        try{
            //String line = null;
            String line = "";
            System.out.println(line.length());
            return; //在return之前,会先finally再return
        }catch(Exception e){
            System.out.println("出错并解决了");
        }finally {
            System.out.println("finally中的代码执行了");
        }

        System.out.println("程序结束了...");

    }
}

package exception;

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

/**
 * 异常处理机制在IO操作中的运用
 */
public class FinallyDemo2 {
    public static void main(String[] args) {
        System.out.println("程序开始了");
        FileOutputStream fos = null;
        try{
            fos = new FileOutputStream("./a/b/fos.dat");
            fos.write(1);
        }catch (IOException e){
            System.out.println("出现IO异常并解决了");
        }finally {
            try {
                if(fos!=null){
                    fos.close();
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("程序结束了");
    }
}

package exception;

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

public class AutoCloseableDemo {
    public static void main(String[] args) {
        System.out.println("程序开始了");

        try(
            //自动关闭特性是编译器认可的,代码编译后会变为FinallyDemo2的样子
            //在try()中定义的内容最终会被编译器修改为finally中调用close()关闭操作
            FileOutputStream fos = new FileOutputStream("fos.dat");

            //只有实现了AutoCloseable接口的类才能在此处定义
            //String str = "abc"; //编译错误
        ){
            fos.write(1);
        }catch(IOException e){
            e.printStackTrace();
        }

        System.out.println("程序结束了");
    }
}

 throw:用于对外主动抛出一个异常,通常下面两种情况我们主动对外抛出异常:

当程序遇到一个满足语法,但是不满足业务要求时,可以抛出一个异常告知调用者。

package exception;

/**
 * 测试异常的抛出
 */
public class Student {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age<0 || age>100){
            throw new RuntimeException(); //抛出了一个异常
        }
        this.age = age;
    }
}

package exception;

/**
 * 异常的抛出
 */
public class ThrowDemo {
    public static void main(String[] args) {
        /*
        Student zs = new Student();
        zs.setAge(1000);
        System.out.println("此人的年龄为:"+zs.getAge()+"岁");
         */

        Student zs = new Student();
        try{
            zs.setAge(1000);
            System.out.println("此人的年龄为:"+zs.getAge()+"岁");
        }catch(RuntimeException e){
            System.out.println("年龄不合法");
        }
    }
}

 

  • 程序执行遇到一个异常,但是该异常不应当在当前代码片段中被解决时可以抛出给调用者。

  • throws:下篇见

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值