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  
    }  
  
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java对象转换工具类_java json字符串转对象

    java对象转换工具类_java json字符串转对象一、引言json字符串现在是项目中很常用的了,尤其是在写接口返回数据一般都是json格式的。小编最近在看项目中,发现有多处地方用到了java对象转json,但是引用的jar包都是不统一的。常见的有由alibaba提供的fastjson、jackson等等一些二、实现引入jar先,jackSon解析JSON,SpringMVC内置的解析器就是这个。<!–Jacks…

    2025年11月18日
    4
  • 独热编码(One-Hot Encoding)介绍及实现

    独热编码(One-Hot Encoding)介绍及实现一、介绍One-Hot编码,又称为一位有效编码,主要是采用位状态寄存器来对个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。独热编码是利用0和1表示一些参数,使用N位状态寄存器来对N个状态进行编码。例如:参考数字手写体识别中:如数字字体识别0~9中,6的独热编码为0000001000自然状态码为:000,001,010,011,100,101…

    2025年8月20日
    5
  • ideal21激活码(JetBrains全家桶)

    (ideal21激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~ML…

    2022年3月21日
    171
  • DVD基础知识

    DVD基础知识感谢‘高人’提供信息本贴的源由是‘hardjoy’碟友的一个提意,说是要弄一个基础知识简介,然后由‘杜比环绕声’版主支持列出了一些基础知识的问题,本人不才,愿就所学逐一介绍,但现在没有时间查书寻求标准答案了,只能想到哪说到哪了,不见得完全准确,大家就对付着看吧。问:有个叫什么磨码什么的是啥意思,好像是说盘基的答:你说的对,通常‘磨码’和‘盘基’是连起来说的,即‘磨码盘基’,同义词还有‘烫码盘基’和

    2022年7月11日
    17
  • Laravel Class config does not exist in

    Laravel Class config does not exist in

    2021年10月26日
    47
  • 如何用正确的姿势发微信群通知?「建议收藏」

    如何用正确的姿势发微信群通知?「建议收藏」人数众多的微信群里,你如何管理通知发放进度?想不想使用更高效的办法发通知?本文推荐给你一款小程序,帮助你轻松搞定微信群通知。(由于微信公众号外部链接的限制,文中的部分链接可能无法正确打开。如有需要,请点击文末的“阅读原文”按钮,访问可以正常显示外链的版本。)两难微信群被用来发通知,其实是工具使用场景错位。因为微信并不是高效办公的工具。否则腾讯也就不必开发企业微信,和

    2022年5月19日
    111

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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