IO流中的字符输入输出流及try...catch处理流处理中的异常

使用字节流读取中文的问题

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

/*
使用字节流读取中文文件
1个中文
    GBK:占用两个字节
    UTF-8:占用3个字节
 */
public class Demo01InputStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("D:\\environment\\java_project\\javase\\c.txt");
        int len = 0;
        while ((len = fis.read())!=-1){
            System.out.println((char)len);//出现错误
        }
        fis.close();
    }
}

字符输入流读取字符数据

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

/*
java.io.Reader:字符输入流,是字符输入流的最顶层的父类,定义了一些共性的成员方法,是一个抽象类

共性的成员方法:
    int read() 读取单个字符并返回
    int read(char[] cbuf) 一次读取多个字符,将字符读入数组
    void close() 关闭该流并释放与之关联的所有资源

java.io.FileReader extends InputStreamReader extends Reader
FileReader:文件字符输入流
作用:把硬盘文件中的数据以字符的方式读取到内存中

构造方法:
    FileReader(String fileName)
    FileReader(File file)
    参数:读取文件的数据源
        String fileName:文件的路径
        File file:一个文件
    FileReader构造方法的作用:
        1.创建一个FileReader对象
        2.会把FileReader对象只想要读取的文件
 */
public class Demo02Reader {
    public static void main(String[] args) throws IOException {
        //1.创建FileReader对象,构造方法中绑定要读取的数据源
        FileReader fr = new FileReader("D:\\environment\\java_project\\javase\\c.txt");
        //2.使用FileReader对象中的方法read读取文件
        //int read() 读取单个字符并返回
        /*int len = 0;
        while ((len = fr.read())!=-1){
            System.out.println((char)len);
        }*/

        //int read(char[] cbuf) 一次读取多个字符,将字符读入数组
        char[] cs = new char[1024];//存储读取到的多个字符
        int len = 0;//记录的是每次读取的有效字符个数
        while((len = fr.read(cs))!=-1){
            /*
            String类的构造方法
            String(char[] value) 把字符数组转换为字符串
            String(char[] value, int offset, int count) 把字符数组的一部分转换为字符串 offset数组的开始索引 count转换的个数
             */
            System.out.println(new String(cs,0,len));
        }

        //3.释放资源
        fr.close();
    }
}

字符输出流FileWriter

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

/*
java.io.Writer:字符输出流,是所有字符输出流的最顶层的父类,是一个抽象类

共性的成员方法:
    - void write(int c) 写入单个字符
    - void write(char[] cbuf) 写入字符数组
    - abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,off数组的开始索引,len写的字符个数
    - void write(String str) 写入字符串
    - void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数
    - void flush() 刷新该流的缓冲
    - void close() 关闭此流,但要先刷新它

java.io.FileWriter extends OutputStreamWriter extends Writer
FileWriter:文件字符输出流
作用:把内存中字符数据写入到文件中

构造方法:
    FileWriter(File file) 根据给定的File对象构造一个FileWriter对象
    FileWriter(String fileName) 根据给定的文件名构造一个FileWriter对象
    参数:写入数据的目的地
        String fileName:文件的路径
        File file:是一个文件
    构造方法的作用:
        1.会创建一个FileWriter对象
        2.会根据构造方法中传递的文件/文件的路径,创建文件
        3.会把FileWriter对象指向创建好的文件

字符输出流的使用步骤(重点):
    1.创建FileWriter对象,构造方法中绑定要写入数据的目的地
    2.使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
    3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
    4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
 */
public class Demo01Writer {
    public static void main(String[] args) throws IOException {
        //1.创建FileWriter对象,构造方法中绑定要写入数据的目的地
        FileWriter fw = new FileWriter("D:\\environment\\java_project\\javase\\d.txt");
        //2.使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
        //void write(int c) 写入单个字符
        fw.write(97);
        //3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
        //fw.flush();
        //4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
        fw.close();
    }
}

FileWriter中flush方法与close方法的区别

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

/*
flush方法和close方法的区别
    - flush:刷新缓冲区,流对象可以继续使用
    - close:先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了
 */
public class Demo02CloseAndFlush {
    public static void main(String[] args) throws IOException {
        //1.创建FileWriter对象,构造方法中绑定要写入数据的目的地
        FileWriter fw = new FileWriter("D:\\environment\\java_project\\javase\\e.txt");
        //2.使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
        //void write(int c) 写入单个字符
        fw.write(97);
        //3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
        fw.flush();
        //刷新之后流可以继续使用
        fw.write(98);

        //4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
        fw.close();

        //close方法之后流已经关闭了,已经从内存中消失了,流就不能再使用了
        fw.write(99);//IOException: Stream closed
    }
}

字符输出流写数据的其他方法

/*
字符输出流写数据的其他方法:
    - void write(char[] cbuf) 写入字符数组
    - abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,off数组的开始索引,len写的字符个数
    - void write(String str) 写入字符串
    - void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数
 */
public class Demo03Writer {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:\\environment\\java_project\\javase\\f.txt");
        char[] cs = {'a','b','c','d','e'};
        //void write(char[] cbuf)写入字符数组
        fw.write(cs);//abcde

        //void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数
        fw.write(cs,1,3);//bcd

        //void write(String str)写入字符串
        fw.write("传智播客");//传智播客

        //void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数
        fw.write("天生我材必有用",0,4);//天生我材

        fw.close();
    }
}

字符输出流的续写和换行

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

/*
续写和换行
续写,追加写:使用两个参数的构造方法
    FileWriter(String fileName, boolean append)
    FileWriter(File file, boolean append)
    参数:
        String fileName,File file:写入数据的目的地
        boolean append:续写开关 true:不会创建新的文件覆盖源文件,可以续写;false:创建新的文件覆盖源文件
换行:换行符号
    windows:\r\n
    linux:/n
    mac:/r
 */
public class Demo04Writer {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("D:\\environment\\java_project\\javase\\g.txt",true);
        for (int i = 0; i < 10; i++) {
            fw.write("HelloWorld"+i+"\r\n");
        }
        fw.close();
    }
}

使用try...catch处理流中的异常

  • try...catch...finally
import java.io.FileWriter;
import java.io.IOException;

/*
在jdk1.7之前使用try  catch   finally 处理流中的异常
格式:
    try{
        可能会产出异常的代码
    }catch(异常类变量 变量名){
        异常的处理逻辑
    }finally{
        一定会执行的代码
        资源释放
    }
 */
public class Demo01TryCatch {
    public static void main(String[] args) {
        //提高变量fw的作用域,让finall可以使用
        //变量在定义的时候,可以没有值,但是使用的时候必须有值
        //fw = new FileWriter("D:\\environment\\java_project\\javase\\g.txt",true);执行失败,fw没有值,fw.close会报错
        FileWriter fw = null;
        try {
            //可能会产生异常的代码
            fw = new FileWriter("W:\\environment\\java_project\\javase\\g.txt",true);
            for (int i = 0; i < 10; i++) {
                fw.write("HelloWorld"+i+"\r\n");
            }

        }catch (IOException e){
            //异常的处理逻辑
            System.out.println(e);
        }finally {
            //一定会执行的代码
            //创建对象失败了,fw的默认值是null,null不能调用方法,会抛出NullPointerException,需要增加一个判断,不是null再把资源释放
            if (fw!=null){
                try {
                    //fw.close方法声明抛出了IOException异常对象,所以我们就得处理这个异常对象,要么throws,要么try...catch
                    fw.close();//Alt+Enter,使用try...catch
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • JDK7的新特性
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
JDK7的新特性
在try的后边可以增加一个(),在括号中可以定义流对象
那么这个流对象的作用域就在try中有效
try中的代码执行完毕,会自动把流对象释放,不用写finally
格式:
    try(定义流对象;定义流对象...){
        可能会产出异常的代码
    }catch(异常类变量 变量名){
        异常的处理逻辑
    }
 */
public class Demo02JDK7 {
    public static void main(String[] args) {
        try (//1.创建一个字节输入流对象,构造方法中绑定要读取的数据流
             FileInputStream fis = new FileInputStream("D:\\environment\\java_project\\javase\\c.txt");
             //2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
             FileOutputStream fos = new FileOutputStream("D:\\environment\\java_project\\javase\\d.txt");){

            //可能会产生异常的代码
            //一次读取一个字节写入一个字节的方式
            //3.使用字节输入流对象中的方法read读取文件
            int len = 0;
            while ((len = fis.read())!=-1){
                //4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
                fos.write(len);
            }
        }catch (IOException e){
            //异常的处理逻辑
            System.out.println(e);
        }
    }
}
  • JDK9的新特性(使用不便)
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
JDK9新特性
try的前边定义流对象
在try后边的()中可以直接引入流对象的名称(变量名)
在try代码执行完毕之后,流对象也可以释放掉,不用写finally
格式:
    A a = new A();
    B b = new B();
    try(a,b){
        可能会产出异常的代码
    }catch(异常类变量 变量名){
        异常的处理逻辑
    }
 */
public class Demo03JDK9 {
    public static void main(String[] args) throws IOException {
        //1.创建一个字节输入流对象,构造方法中绑定要读取的数据流
        FileInputStream fis = new FileInputStream("D:\\environment\\java_project\\javase\\c.txt");
        //2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
        FileOutputStream fos = new FileOutputStream("D:\\environment\\java_project\\javase\\d.txt");

        try (fis;fos){
            //一次读取一个字节写入一个字节的方式
            //3.使用字节输入流对象中的方法read读取文件
            int len = 0;
            while ((len = fis.read())!=-1){
                //4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
                fos.write(len);
            }
        }catch (IOException e){
            System.out.println(e);
        }
        fos.write(1);//Stream closed
    }
}
posted @ 2021-12-04 21:35  wydilearn  阅读(455)  评论(0编辑  收藏  举报