`
810364804
  • 浏览: 787505 次
文章分类
社区版块
存档分类
最新评论

Java_io体系之OutputStreamWriter、InputStreamReader简介、走进源码及示例——17

 
阅读更多

Java_io体系之OutputStreamWriter、InputStreamReader简介、走进源码及示例——17

一:OutputStreamWriter

1、类功能简介:

输入字符转换流、是输入字节流转向输入字符流的桥梁、用于将输入字节流转换成输入字符流、通过指定的或者默认的编码将从底层读取的字节转换成字符返回到程序中、与OutputStreamWriter一样、本质也是使用其内部的一个类来完成所有工作:StreamDecoder、使用默认或者指定的编码将字节转换成字符、InputStreamReader只是对StreamDecoder进行了封装、isr内部所有方法核心都是调用StreamDecoder来完成的、InputStreamReader只是对StreamDecoder进行了封装、使得我们可以直接使用读取方法、而不用关心内部实现。

2、OutputStreamWriter API简介:


A:关键字


	private final StreamEncoder se;		核心类、用于将字符编码成字节


B:构造方法


	OutputStreamWriter(OutputStream out, String charsetName)	创建使用指定字符集的 OutputStreamWriter。
	
	OutputStreamWriter(OutputStream out, Charset cs)	 创建使用给定字符集的 OutputStreamWriter。	
	
	OutputStreamWriter(OutputStream out)	 创建使用默认字符编码的 OutputStreamWriter。
	
	OutputStreamWriter(OutputStream out, CharsetEncoder enc)	创建使用给定字符集编码器的 OutputStreamWriter。


C:一般方法


	String getEncoding()	 返回此流使用的字符编码的名称。	
	
	void write(int c)	写入单个字符。
	
	void write(char cbuf[], int off, int len)	 写入字符数组的某一部分。
	
	void write(String str, int off, int len)	  写入字符串的某一部分。
	
	void flush()	刷新该流的缓冲。
	
	void close()	关闭此流,但要先刷新它。


3、源码分析


package com.chy.io.original.code;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;


/**
 * 字符输出流、是使用指定的编码或者时系统默认的编码将字节转换成字符。
 * 是OutputStream转换成Writer的桥梁、也是PrintStream、能够在构造的时候指定编码的关键。
 * 实际上是将OutputStream传递给了StreamEncoder来操作out
 */

public class OutputStreamWriter extends Writer {

	//通过StreamEncoder se进行字节与字符的转码。
    private final StreamEncoder se;

    /**
     * 用指定的编码将OutputStream out转换成OutputStreamWriter。
     */
    public OutputStreamWriter(OutputStream out, String charsetName)
	throws UnsupportedEncodingException
    {
    	// 调用父类Writer的构造方法创建一个新的字符流 writer,其关键部分将同步给自身。
		super(out);
		if (charsetName == null)
		    throw new NullPointerException("charsetName");
		//初始化StreamEncoder se.
		se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
	}

    /**
     * 使用默认编码创建osw。
     */
    public OutputStreamWriter(OutputStream out) {
	super(out);
	try {
	    se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
	} catch (UnsupportedEncodingException e) {
	    throw new Error(e);
        }
    }

    /**
     * 使用指定的字符集创建osw
     */
    public OutputStreamWriter(OutputStream out, Charset cs) {
	super(out);
	if (cs == null)
	    throw new NullPointerException("charset");
	se = StreamEncoder.forOutputStreamWriter(out, this, cs);
    }

    /**
     * 使用指定的字符编码创建osw
     */
    public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {
	super(out);
	if (enc == null)
	    throw new NullPointerException("charset encoder");
	se = StreamEncoder.forOutputStreamWriter(out, this, enc);
    }

    /**
     * 获取字符流使用的字符集、或者编码
     */
    public String getEncoding() {
    	return se.getEncoding();
    }

    /**
     * 将osw中的字符flush到底层OutputStream中、此方法不包含flush底层out中的字节
     */
    void flushBuffer() throws IOException {
    	se.flushBuffer();
    }

    /**
     * 将字节转换成字符后、向out中写入一个字符(字符的编码在构造OutputStreamWriter时指定或者使用默认编码
     */
    public void write(int c) throws IOException {
    	se.write(c);
    }

    /**
     * 将cbuf中的一部分写入到out中
     */
    public void write(char cbuf[], int off, int len) throws IOException {
    	se.write(cbuf, off, len);
    }

    /**
     * 将str一部分写入到out中
     */
    public void write(String str, int off, int len) throws IOException {
    	se.write(str, off, len);
    }

    /**
     * flush此流、实际上是调用StreamEncoder的flush方法、
     */
    public void flush() throws IOException {
    	se.flush();
    }

    /**
     * 关闭StreamEncoder、即关闭OutputSteramWriter.
     */
    public void close() throws IOException {
    	se.close();
    }
}


4、实例演示:



package com.chy.io.test;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class OutputStreamWriterTest {
	
	private final static String str = "威尔杰克逊";
	
	
	public static void testOutputStreamWriterTest()throws IOException{
		File file = new File("D:" + File.separator + "osw.txt");
		//设置文件内容可追加
		FileOutputStream fos = new FileOutputStream(file, true);
		
		OutputStreamWriter oswDefault = new OutputStreamWriter(fos);
		BufferedWriter bwDefault = new BufferedWriter(oswDefault);
		//第一个“威尔杰克逊”
		bwDefault.write(str);
		bwDefault.newLine();
		System.out.println("oswDefault encoding: " + oswDefault.getEncoding());
		
		
		OutputStreamWriter oswGBK = new OutputStreamWriter(fos, "GBK");
		BufferedWriter bwGBK = new BufferedWriter(oswGBK);
		//第二个“威尔杰克逊”
		bwGBK.write(str);
		bwGBK.newLine();
		System.out.println("bwGBK encoding: " + oswGBK.getEncoding());
		
		
		OutputStreamWriter oswUTF8 = new OutputStreamWriter(fos, "UTF-8");
		BufferedWriter bwUTF8 = new BufferedWriter(oswUTF8);
		//第三个“威尔杰克逊”
		bwUTF8.write(str);
		bwUTF8.newLine();
		System.out.println("bwGBK encoding: " + oswUTF8.getEncoding());
		
		/**关闭流、释放资源
		 * 自己可以尝试分析为什么不能写成下面这种形式?
		 * 
		bwDefault.flush();
		bwDefault.close();
		
		bwGBK.flush();
		bwGBK.close();
		
		bwUTF8.flush();
		bwUTF8.close();
		
		fos.flush();
		fos.close();
		*/
		
		/**关闭流、释放资源*/
		bwDefault.flush();
		bwGBK.flush();
		bwUTF8.flush();
		
		bwDefault.close();
		bwGBK.close();
		bwUTF8.close();
	}
	
	public static void main(String[] args) throws IOException{
		testOutputStreamWriterTest();
	}
}


二:InputStreamReader


1、类功能简介:


输出字符转换流、是输出字节流通向输出字符流的桥梁、用于将字节输出流转换成字符输出流、也就是完成将要写入的字符使用特定的编码转码成字节、再将转换后的字节写入到底层字节输出流中。可以指定编码。本质是OutputStreamWriter内部的一个类:StreamEncoder、这个类来完成上面所有的工作、是这个类使用指定的或者默认的编码来将要写入的字符转码成字节、然后调用StreamEncoder的方法来将转码后的字节写入到底层流中OutputStreamWriter中所有的方法都是调用StreamEncoder来实现的、OutputStreamWriter只是对StreamEncoder进行了封装、什么都没有做、


2、InputStreamReader API简介:


A:关键字


	private final StreamDecoder sd;		核心类、用于将字节解码成字符

B:构造方法


	InputStreamReader(InputStream in)	创建一个使用默认字符集的 InputStreamReader。
	
	InputStreamReader(InputStream in, String charsetName)	创建使用指定字符集的 InputStreamReader。
	
	InputStreamReader(InputStream in, Charset cs)	 创建使用给定字符集的 InputStreamReader。
	
	InputStreamReader(InputStream in, CharsetDecoder dec)	创建使用给定字符集解码器的 InputStreamReader。


C:一般方法


	String getEncoding()	返回此流使用的字符编码的名称。
	
	int read()	 读取单个字符。
	
	int read(char cbuf[], int offset, int length)	将字符读入数组中的某一部分。
	
	boolean ready()		判断此流是否已经准备好用于读取。
	
	void close()	关闭该流并释放与之关联的所有资源。


3、源码分析


package com.chy.io.original.code;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;



/**
 * 字符输入流、是连接字节流与字符流之间的桥梁。将读取的字节转换成字符、编码可以使用系统默认的也可以使用指定的。
 * 为提高效率、一般结合BufferedReader使用。
 *
 * @version 	1.1, 13/11/16
 * @author		andyChen

 */

public class InputStreamReader extends Reader {
	//可以使用指定编码读取字节的本质。使用其将byte解码成字符串返回。
	//对应的OutputStreamWriter中的StreamEncoder将字节编码成字符写入out中。
	//对使用OutputStreamWriter写入的out读取时、注意编码。否则会造成乱码。
    private final StreamDecoder sd;

    /**
     * 使用默认编码将字节输入流InputStream in转换成字符输入流
     */
    public InputStreamReader(InputStream in) {
	super(in);
        try {
	    sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
	    // The default encoding should always be available
	    throw new Error(e);
	}
    }

    /**
     * 使用指定的字符集将in转换成isr.
     */
    public InputStreamReader(InputStream in, Charset cs) {
        super(in);
	if (cs == null)
	    throw new NullPointerException("charset");
	sd = StreamDecoder.forInputStreamReader(in, this, cs);
    }

    /**
     * 使用指定的字符编码将in转换成isr
     */
    public InputStreamReader(InputStream in, CharsetDecoder dec) {
        super(in);
		if (dec == null)
		    throw new NullPointerException("charset decoder");
		sd = StreamDecoder.forInputStreamReader(in, this, dec);
    }

    /**
     * 获取此流的编码
     */
    public String getEncoding() {
    	return sd.getEncoding();
    }
    
    //读取单个字符
    public int read() throws IOException {
        return sd.read();
    }

    //将字符读取到cbuf中
    public int read(char cbuf[], int offset, int length) throws IOException {
    	return sd.read(cbuf, offset, length);
    }

    //查看此流是否可读
    public boolean ready() throws IOException {
    	return sd.ready();
    }

    //关闭此流释放资源
    public void close() throws IOException {
    	sd.close();
    }
}

4、实例演示:


package com.chy.io.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

public class InputStreamReaderTest {
	private static File file = new File("D:" + File.separator + "osw.txt");
	private static FileInputStream fis;
	static{
		try {
			fis = new FileInputStream(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public static void testISRDefaultEncoder()throws IOException{
		//使用默认编码读取文件中的第一“威尔杰克逊”
		InputStreamReader isrDefault = new InputStreamReader(fis);
		BufferedReader bisDefault = new BufferedReader(isrDefault);
		System.out.println("isr encoding : " + isrDefault.getEncoding() + "======str: " + bisDefault.readLine());
		bisDefault.close();
	}
	
	public static void testISRGBK() throws IOException{
		//使用GBK读取第一个“威尔杰克逊”
		InputStreamReader isrGBK = new InputStreamReader(fis, "GBK");
		BufferedReader bisGBK = new BufferedReader(isrGBK);
		System.out.println("isr encoding : " + isrGBK.getEncoding() + "=====str: " + bisGBK.readLine());
		bisGBK.close();
	}
	
	public static void testISRUTF8() throws IOException{
		//使用UTF-8读取文件中的第一个“威尔杰克逊”
		InputStreamReader isrUFT8 = new InputStreamReader(fis, "UTF-8");
		BufferedReader bisUFT8 = new BufferedReader(isrUFT8);
		System.out.println("isr encoding : " + isrUFT8.getEncoding() + "=====str: " + bisUFT8.readLine());
		bisUFT8.close();
	}
	
	public static void main(String[] args) throws IOException{
		testISRDefaultEncoder();
		//testISRGBK();
		//testISRUTF8();
		
	}
}


总结:


OutputStreamWriter、InputStreamReader分别为InputStream、OutputStream的低级输入输出流提供将字节转换成字符的桥梁、他们只是外边的一个门面、真正的核心:

OutputStreamWriter中的StreamEncoder:

1、使用指定的或者默认的编码集将字符转码为字节

2、调用StreamEncoder自身实现的写入方法将转码后的字节写入到底层字节输出流中。

InputStreamReader中的StreamDecoder:

1、使用指定的或者默认的编码集将字节解码为字符

2、调用StreamDecoder自身实现的读取方法将解码后的字符读取到程序中。

在理解这两个流的时候要注意:java——io中只有将字节转换成字符的类、没有将字符转换成字节的类、原因很简单——字符流的存在本来就像对字节流进行了装饰、加工处理以便更方便的去使用、在使用这两个流的时候要注意:由于这两个流要频繁的对读取或者写入的字节或者字符进行转码、解码和与底层流的源和目的地进行交互、所以使用的时候要使用BufferedWriter、BufferedReader进行包装、以达到最高效率、和保护存储介质。


更多IO内容:java_io 体系之目录



分享到:
评论

相关推荐

    JAVA IO流缓冲字节流缓冲字符流等流经典代码示例加注释总结.rar

    2、常用21个IO流:FileWriter、FileReader、CharArrayReader、CharArrayWriter、CharSequence、OutputStreamWriter、FileOutputStream、InputStreamReader、PrintWriter、BufferedReader、InputStream、...

    Java中的InputStreamReader和OutputStreamWriter源码分析_动力节点Java学院整理

    本文通过示例代码给大家解析了Java中的InputStreamReader和OutputStreamWriter知识,需要的的朋友参考下吧

    Java Socket 操作 Demo

    import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing....

    java项目超市

    import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; ...

    Java I/O 第二版

    OReilly.Java.I.O.2nd.Edition.May.2006 Java的io包主要包括: 1. 两种流:字节流(byte Stream)和字符流(character stream),这...3. 一个桥梁:将字节流转变为字符流的InputStreamReader和OutputStreamWriter。

    Java设计模式

    ● java.io.InputStreamReader(InputStream) ● java.io.OutputStreamWriter(OutputStream) ● javax.xml.bind.annotation.adapters.XmlAdapter#marshal() ● javax.xml.bind.annotation.adapters.XmlAdapter#...

    (超赞)JAVA精华之--深入JAVA API

    1.3.9 字符流 InputStreamReader/OutputStreamWriter 1.3.10 随机存取文件 RandomAccessFile 1.3.11 小结 1.4 java中的一些常用词汇 1.5 J2SE学习中的30个基本概念 1.6 Java线程 1.7 Java 5.0多线程编程 1.8 Java ...

    JavaIo流分析图

    分析Java常用IO流,包括InputStream、OutputStream、FileInputStream、FileOutputStream、BufferedInputStream、BufferedOutputStream、Reader、Writer、InputStreamReader、OutputStreamWriter、FileReader、...

    Java之IO流学习总结

    Java IO流学习总结 Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据...

    JAVA设计模式之适配器模式.docx

    适配器模式在源码中的应用: (1)JDK源码的IO模块用到,例如 java.io.InputStreamReader(InputStream)、java.io.OutputStreamWriter(OutputStream)。 (2)mybatis源码日志模块用到对象适配器模式。

    java 爬网 程序 示例

    import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; public class GetNetHtml { public static String createhttpClient...

    一个简单的一对一 聊天系统

    import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing....

    java万年历源代码

    import java.io.InputStreamReader; import java.io.OutputStreamWriter; //import java.sql.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util...

    JDK_API_1_6

    Serializable 类通过实现 java.io.Serializable 接口以启用其序列化功能。 类摘要 BufferedInputStream BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。 ...

    JavaIO流精讲上

    课程内容主要有:File类概述、File类功能讲解、JAVA IO流概述、字节流、字符流、缓冲流、InputStream、OutputStream、Reader、Writer、FileInputStream、FileOutputStream、InputStreamReader、OutputStreamWriter、...

    wsdl文件解析

    //import java.io.OutputStreamWriter; import java.io.PrintStream; //import java.nio.charset.Charset; //import java.nio.charset.CharsetEncoder; import java.util.Iterator; import java.util.List; ...

    java 文件存储 Inputstream outputstream reader writer的用法

    当你还是一个java初学者的时候,是不是还在为你没有一个好的源代码模仿去学习而烦恼,这个代码很容易看懂,对你学习很有帮助

    java解析给定url

    import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net....

    利用Java代码实现无字符+中文转换为全中文的代码

    import java.io.InputStreamReader; import java.io.OutputStreamWriter; import com.vince.*; /** * 将本地文件以哪种编码输出 * @param inputfile 输入文件的路径 * @param outfile 输出文件的路径 * @param ...

    Java文件操作类FileManager

    读写文件是常用的操作之一,每次将相应的代码片段复制过来不仅麻烦,还会影响整体的... import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.L

Global site tag (gtag.js) - Google Analytics