在Java中,上述三个类经常用于处理数据流,下面介绍一下三个类的不同之处以及各自的用法。
InputStream : 是所有字节输入流的超类,一般使用它的子类:FileInputStream等,它能输出字节流;
InputStreamReader : 是字节流与字符流之间的桥梁,能将字节流输出为字符流,并且能为字节流指定字符集,可输出一个个的字符;
BufferedReader : 提供通用的缓冲方式文本读取,readLine读取一个文本行, 从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
下面有三个小案例(访问百度主页获取字节流然后输出)来分别说明三个类的作用:
InputStream:
package InputStream;import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;public class Test_InputStream {/*** 获取字节流* @param url* @return*/private String getStream(String url){//获取字节流InputStream in = null;String result = "";try {in = new URL(url).openStream();int tmp;while((tmp = in.read()) != -1){result += (char)tmp;}} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//输出字节流return result;}public static void main(String[] args){String URL = "http://www.baidu.com";Test_InputStream test = new Test_InputStream();System.out.println(test.getStream(URL));}
}
通过URL连接获取了InputStream流连接,然后通过read方法来一个字节一个字节的读取字节流并组合在一起(read方法返回-1则数据读取结束),最后以reasults返回。
输出如下:
60 33 68 79 67 84 89 80 69 32 104 116 109 108 62 60 33 45 45 83 84 65 84 ……
这就是字节流,每个数字都是一个字节(Byte,8位),所以如果读取英文的话,用字节流,然后用(char)强制转化一下就行了,但如果有中文等双字节语言或者说需要指定字符编码集的情况,就必须用到InputStreamReader将字节流转化为字符流了。
InputStreamReader:
package InputStreamReader;import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;public class Test_InputStreamReader {/** 得到字符流前需先有字节流*/private String getStream(String url){try {//得到字节流InputStream in = new URL(url).openStream();//将字节流转化成字符流,并指定字符集InputStreamReader isr = new InputStreamReader(in,"UTF-8");String results = "";int tmp;while((tmp = isr.read()) != -1){results += (char)tmp;}return results;} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubString URL = "http://www.baidu.com";Test_InputStreamReader test = new Test_InputStreamReader();System.out.println(test.getStream(URL));}}
先获取字节流,然后创建InputStreamReader将字节流转化成字符流,并指定其字符集为UTF-8,然后使用强制转化将read到的int字节转化为char型,此时已可以输出中文字符,并且可速度上看出,输出字符流比输出字节流要快。
下面是结果的部分截图:
BufferedReader:
package BufferedReader;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;public class Test_BufferedReader {/** 字节流——字符流——缓存输出的字符流*/private String getStream(String url){try {//得到字节流InputStream in = new URL(url).openStream();//将字节流转化成字符流,并指定字符集InputStreamReader isr = new InputStreamReader(in,"UTF-8");//将字符流以缓存的形式一行一行输出BufferedReader bf = new BufferedReader(isr); String results = "";String newLine = "";while((newLine = bf.readLine()) != null){results += newLine+"\n";}return results;} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubString URL = "http://www.baidu.com";Test_BufferedReader test = new Test_BufferedReader();System.out.println(test.getStream(URL));}}
获取字符流后,可直接缓存,然后从缓存区取出,这时的速度比InputStreamReader又将快上很多。输出结果同上。
总结 :
在读取网络数据流的时候,可以先通过用InputStream获取字节流、InputStreamReader将字节流转化成字符流、BufferedReader将字符流以缓存形式输出的方式来快速获取网络数据流。