IO流(五) IO异常及转换流

我们在实际开发中,对异常时如何处理的

public class FileOutputStreamDemo3 {
	public static void main(String[] args) {
		File file = new File("c:\\file.txt");
		//定义FileOutputStream的引用
		FileOutputStream fos = null;
		try {
			//创建FileOutputStream对象
			fos = new FileOutputStream(file);
			//写出数据
			fos.write("abcde".getBytes());
		} catch (IOException e) {
			System.out.println(e.toString() + "----");
		} finally {
			//一定要判断fos是否为null,只有不为null时,才可以关闭资源
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					throw new RuntimeException("");
				}
			}
		}
	}
}
public class HandleException1 {
    public static void main(String[] args) {
      	// 声明变量
        FileWriter fw = null;
        try {
            //创建流对象
            fw = new FileWriter("fw.txt");
            // 写出数据
            fw.write("tt"); //tt
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

转换流

在学习字符流(FileReader、FileWriter)的时候,其中说如果需要指定编码和缓冲区大小时,可以在字节流的基础上,构造一个InputStreamReader或者OutputStreamWriter,这又是什么意思呢?

OutputStreamWriter类

查阅OutputStreamWriter的API介绍,OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节。它的作用的就是,将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去。

    public static void writeCN() throws Exception {
		//创建与文件关联的字节输出流对象
		FileOutputStream fos = new FileOutputStream("c:\\cn8.txt");
		//创建可以把字符转成字节的转换流对象,并指定编码
		OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
		//调用转换流,把文字写出去,其实是写到转换流的缓冲区中
		osw.write("你好");//写入缓冲区。
		osw.close();
	}

OutputStreamWriter流对象,它到底如何把字符转成字节输出的呢?

其实在OutputStreamWriter流中维护自己的缓冲区,当我们调用OutputStreamWriter对象的write方法时,会拿着字符到指定的码表中进行查询,把查到的字符编码值转成字节数存放到OutputStreamWriter缓冲区中。然后再调用刷新功能,或者关闭流,或者缓冲区存满后会把缓冲区中的字节数据使用字节流写到指定的文件中。

java.io.OutputStreamWriter extends Writer

OutputStreamWriter: 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。(编码:把能看懂的变成看不懂)

 

继续自父类的共性成员方法:

    - 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() 关闭此流,但要先刷新它。

构造方法:

    OutputStreamWriter(OutputStream out)创建使用默认字符编码的 OutputStreamWriter。

    OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。

    参数:

        OutputStream out:字节输出流,可以用来写转换之后的字节到文件中

        String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,...不指定默认使用UTF-8

使用步骤:

    1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称

    2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)

    3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)

    4.释放资源

 

InputStreamReader类

查阅InputStreamReader的API介绍,InputStreamReader 是字节流通向字符流的桥梁:它使用指定的字符编码表读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

 

java.io.InputStreamReader extends Reader

InputStreamReader:是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。(解码:把看不懂的变成能看懂的)

 

继承自父类的共性成员方法:

    int read() 读取单个字符并返回。

    int read(char[] cbuf)一次读取多个字符,将字符读入数组。

    void close() 关闭该流并释放与之关联的所有资源。

构造方法:

    InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。

    InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。

    参数:

        InputStream in:字节输入流,用来读取文件中保存的字节

        String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,...不指定默认使用UTF-8

 使用步骤:

    1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称

    2.使用InputStreamReader对象中的方法read读取文件

    3.释放资源

 注意事项:

    构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码

代码演示

public class InputStreamReaderDemo {
	public static void main(String[] args) throws IOException {
		//演示字节转字符流的转换流
		readCN();
	}
	public static void readCN() throws IOException{
		//创建读取文件的字节流对象
		InputStream in = new FileInputStream("c:\\cn8.txt");
		//创建转换流对象 
		//InputStreamReader isr = new InputStreamReader(in);这样创建对象,会用本地默认码表读取,将会发生错误解码的错误
        InputStreamReader isr = new InputStreamReader(in,"utf-8");
		//使用转换流去读字节流中的字节
		int ch = 0;
		while((ch = isr.read())!=-1){
			System.out.println((char)ch);
		}
		//关闭流
		isr.close();
	}
}

注意:在读取指定的编码的文件时,一定要指定编码格式,否则就会发生解码错误,而发生乱码现象。

转换流和子类区别

发现有如下继承关系:

OutputStreamWriter:

|--FileWriter:

InputStreamReader:

|--FileReader;

 

父类和子类的功能有什么区别呢?

OutputStreamWriter和InputStreamReader是字符和字节的桥梁:也可以称之为字符转换流。字符转换流原理:字节流+编码表。

FileWriter和FileReader:作为子类,仅作为操作字符文件的便捷类存在。当操作的字符文件,使用的是默认编码表时可以不用父类,而直接用子类就完成操作了,简化了代码。

InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));//默认字符集。

InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");//指定GBK字符集。

FileReader fr = new FileReader("a.txt");

这三句代码的功能是一样的,其中第三句最为便捷。

注意:一旦要指定其他编码时,绝对不能用子类,必须使用字符转换流。什么时候用子类呢?

条件:

1、操作的是文件。2、使用默认编码。

总结:

字节--->字符 : 看不懂的--->看的懂的。  需要读。输入流。 InputStreamReader

字符--->字节 : 看的懂的--->看不懂的。  需要写。输出流。 OutputStreamWriter

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值