inputstreamreader和inputstream_FileInputStream我们的机器只会读字节码,而我们人却很难读懂字节码,所以人与机器交流过程中需要编码解码。InputStreamReader及其子类FileReader:(从字节到字符)是个解码过程;OutputStreamWrite及其子类FileWriter:(从字符到字节)是个编码过程。InputStreamReader这个解码过程中,最主要的就是StreamDecoder类
大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
我们的机器只会读字节码,而我们人却很难读懂字节码,所以人与机器交流过程中需要编码解码。
InputStreamReader及其子类FileReader:(从字节到字符)是个解码过程;【字节流转换成字符流】
OutputStreamWrite及其子类FileWriter:(从字符到字节)是个编码过程。
InputStreamReader这个解码过程中,最主要的就是
StreamDecoder类
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账号...