inputstreamreader和inputstream_FileInputStream

inputstreamreader和inputstream_FileInputStream我们的机器只会读字节码,而我们人却很难读懂字节码,所以人与机器交流过程中需要编码解码。InputStreamReader及其子类FileReader:(从字节到字符)是个解码过程;OutputStreamWrite及其子类FileWriter:(从字符到字节)是个编码过程。InputStreamReader这个解码过程中,最主要的就是StreamDecoder类 

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用
我们的机器只会读字节码,而我们人却很难读懂字节码,所以人与机器交流过程中需要编码解码。

InputStreamReader及其子类FileReader:(从字节到字符)是个解码过程;【字节流转换成字符流】
OutputStreamWrite及其子类FileWriter:(从字符到字节)是个编码过程。
InputStreamReader这个解码过程中,最主要的就是
StreamDecoder
 
inputstreamreader和inputstream_FileInputStream
InputStream到Reader的过程
要指定编码字符集
否则将采用操作系统默认字符集,很可能会出现乱码问题。(查看JDK中的InputStreamReader类的构造函数,除了第一个构造函数没有制定外,其他几个都需要指定)
如果看不懂这个图请先看Association,Aggregation and Composition这篇文章。
现在对于这张图我们还有个难点没有解决:
StreamDecoder是个什么东西
?这个,这个工作就有点复杂了,网上资料比较少,我自己找
源码
看看:
[java]  
public class InputStreamReader extends Reader {  
    private final StreamDecoder sd;//由上图已知在InputStreamReader中一定有一个StreamDecoder对象  
    public InputStreamReader(InputStream in) {//InputStreamReader有多个构造方法,我假设它用的就是这个  
        super(in);  
        try {  
              //
创建一个StreamDecoder对象  
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // 用
系统默认编码  
        } catch (UnsupportedEncodingException e) {  
            // The default encoding should always be available  
            throw new Error(e);  
        }  
    }  
    public int read() throws IOException {  
        // 看猫腻来了,竟然
实际上是StreamDecoder在read  
        return sd.read();  
    }  
/**其他的方法我们不管,看有关的就行**/  
}  
好,再来看看JDK7中的StreamDecoder(eclipse中显示不出,我也不知道为什么,我在这个网址看的源码点一下)是怎么实现的:  
public class StreamDecoder extends Reader{  
    private static final int MIN_BYTE_BUFFER_SIZE = 32;  
    private static final int DEFAULT_BYTE_BUFFER_SIZE = 8192;  
    private Charset cs;  
    private CharsetDecoder decoder;  
    private ByteBuffer bb;  
  
    // 由上述的 forInputStreamReader方法的参数可知用的是下面这个方法  
    public static StreamDecoder forInputStreamReader(InputStream in,Object lock,String charsetName) throws UnsupportedEncodingException {  
        String csn = charsetName;  
       if (csn == null) //
由于用的是默认编码,会执行这句  
       csn = Charset.defaultCharset().name();  
       try {  
        if (Charset.isSupported(csn))   // 检测JVM是否支持该编码集  
                  
              return new StreamDecoder(in, lock, Charset.forName(csn));  
       } catch (IllegalCharsetNameException x) { }  
              throw new UnsupportedEncodingException (csn);  
    }  
      
    StreamDecoder(InputStream in, Object lock, Charset cs) {  
        this(in, lock, cs.newDecoder().onMalformedInput(CodingErrorAction  
                        .REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE));  
        // 额,说明它是在
用Charset对象产生CharsetDecoder对象,目的是为了执行另一个构造函数  
    }  
  
    StreamDecoder(InputStream in, Object lock, CharsetDecoder dec) {  
        //
 CharsetDecoder:是一个引擎,可以将一个字节序列按照特定的字符集转换成一个16位的Unicode序列  
             super(lock);  
             this.cs = dec.charset();  
             this.decoder = dec;  
        // 下面的代码先不用管,我们这里用不上  
             // This path disabled until direct buffers are faster  
             if (false && in instanceof FileInputStream) {  
                    ch = getChannel((FileInputStream)in);  
                    if (ch != null)  
                        bb = ByteBuffer.allocateDirect(DEFAULT_BYTE_BUFFER_SIZE);  
                }  
                if (ch == null) {  
                    this.in = in;  
                    this.ch = null;  
                    bb = ByteBuffer.allocate(DEFAULT_BYTE_BUFFER_SIZE);  
                }  
                bb.flip();                      // So that bb is initially empty  
    }  
    // 调用的就是这个函数吧  
    public int read() throws IOException {  
        return read0(); //额,又是假的;继续看  
    }  
    private int read0() throws IOException {  
        synchronized (lock) {  
            // Return the leftover char, if there is one  
            if (haveLeftoverChar) {  
                haveLeftoverChar = false;  
                return leftoverChar;  
            }  
            // Convert more bytessz  
            char cb[] = new char[2];    //一次读两个字节  
            int n = read(cb, 0, 2);  
            switch (n) {  
                case -1:  
                    return -1;  
                case 2:  
                    leftoverChar = cb[1];  
                    haveLeftoverChar = true;  
                // FALL THROUGH  
                case 1:  
                    return cb[0];  
                default:  
                    assert false : n;  
                    return -1;  
            }// end of catch  
        }// end of  synchronized  
    }  
  
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/189388.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • phpstorm 中背景色的调整

    phpstorm 中背景色的调整

  • 利用JDK发布webService实例「建议收藏」

    利用JDK发布webService实例「建议收藏」一、webService的发布1、新建一个webProject2、修改jdk为1.6及以上—-3、编写方法—- packagecom.test.webService;importjavax.jws.WebService;importjavax.xml.ws.Endpoint;@WebServicepublicclass

  • Java内存模型是什么,为什么要有Java内存模型,Java内存模型解决了什么问题等。。。

    Java内存模型是什么,为什么要有Java内存模型,Java内存模型解决了什么问题等。。。本文中,有很多定义和说法,都是笔者自己理解后定义出来的。希望能够让读者可以对Java内存模型有更加清晰的认识。当然,如有偏颇,欢迎指正。 为什么要有内存模型 在介绍Java内存模型之前,先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上做了哪些事情。要说计算机的内存模型,就要说一下一段古老的历史,看一下为什么要有内存模型。内存模型,英文名…

  • Python删除字符串中指定字符

    Python删除字符串中指定字符删除特定位置字符使用.pop()方法,先将字符串转换为列表,再把列表转换成字符串。string1=’雪雪最大’#定义一个字符串list_str=list(string1)#将字符串转换为列表list_str.pop(1)#删去第一个字符string2=”.join(list_str)#再将列表转换成字符串print(string2)输出结果雪最大 删除指定字符方法一使用.replace()方法,删除(指定字符string=’雪雪最大’

  • java 对象转map,去掉null

    java 对象转map,去掉nullpublicstaticMap<String,Object>beanToMap(Objectobject){Map<String,Object>map=null;try{map=newHashMap<String,Object>();Bean…

  • 创建数组的两种方式

    创建数组的两种方式1.通过构造函数创建数组1.1let变量名称=newArray(size)//创建一个指定大小的数组1.2let变量名称=newArray()//创建一个空的数组1.3let变量名称=newArray(data1,data2,…)//创建一个带数据的数组2.通过字面量创建数组2.1 let变量名称=[]创建一个空数组…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号