大家好,又见面了,我是你们的朋友全栈君。
简介
OutputStreamWriter和InputStreamReader是字节流和字符流转化之间桥梁,OutputStreamWriter继承自Writer接口,而InputStreamReader继承自接口Reader.需要了解的一点是字符流的写入和读取的方式.
- 字符输出流:将字符通过指定编码方式转化成字节数据,然后存储到文件中.
- 字符输入流:读取文件的字节数据通过相同的编码方式转化成字符.不同的编码方式会造成乱码.
1.InputStreamReader是字节流转化成字符流的桥梁.通过给定字符编码方式或者传入指定编码方式,平台默认编码方式等将字节转化成字符读取到流中.子类有FileReader.
2.OutputStreamWriter是字符流转化成字节流的桥梁,通过给定字符编码方式或者传入指定编码方式,平台默认编码方式等将字符转化成字节写到流中.子类有FileWriter.
OutputStreamWriter介绍
1.构造方法.
代码语言:javascript复制public OutputStreamWriter(OutputStream out, String charsetName){}
public OutputStreamWriter(OutputStream out) {}
public OutputStreamWriter(OutputStream out, Charset cs) {}
public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {}
四个有参构造方法,区别是编码传入方式.分别是:
- 创建一个指定了底层字节输出流和”指定”字符编码名称charsetName的OutputStreamWriter流.
- 创建一个指定了底层字节输出流和默认字符编码方式的OutputStreamWriter流.
- 创建一个指定底层字节输出流和”给定”字符编码方式cs的OutputStreamWriter流.
- 创建一个 指定底层字节输出流和”给定”字符编码器enc的OutputStreamWriter流.
2.内部变量
代码语言:javascript复制private final StreamEncoder se;
- 负责字符编码的类StreamEncoder.
3.内部方法
代码语言:javascript复制public String getEncoding()
public void write(int c){}
public void write(char cbuf[], int off, int len){}
public void write(String str, int off, int len){}
public void flush() {}
public void close() {}
- getEncoding()—-获取字符编码方式.
- write(int c)—将单个字符写到流中.
- write(char cbuf[],int off,int len)–将字符数组cbuf中,off位置开始,len个字符写到流中.
- write(String str,int off,int len)—将字符串str中,off位置开始,len个字符写到流中.
- flush()—刷新流.
- close()—关闭流,释放相关资源.
InputStreamReader介绍
1.构造方法.
代码语言:javascript复制public InputStreamReader(InputStream in) {}
public InputStreamReader(InputStream in, String charsetName){}
public InputStreamReader(InputStream in, Charset cs) {}
public InputStreamReader(InputStream in, CharsetDecoder dec) {}
与OutputStreamWriter流相对应的四种有参构造方法,根据对应的字符编码方式将数据解码读取.
- 创建一个指定了底层字节输出流和默认字符编码方式的InputStreamReader流.
- 创建一个指定了底层字节输出流和”指定”字符编码名称charsetName的InputStreamReader流.
- 创建一个指定底层字节输出流和”给定”字符编码方式cs的InputStreamReader流.
- 创建一个 指定底层字节输出流和”给定”字符编码器dec的InputStreamReader流.
2.内部变量
代码语言:javascript复制private final StreamDecoder sd;
- 负责字符解码的类StreamDecoder.
3.内部方法
代码语言:javascript复制public String getEncoding() {}
public int read(){}
public int read(char cbuf[], int offset, int length){}
public boolean ready(){}
public void close(){}
- getEncoding()—获取字符编码方式
- read()—从流中读取单个字符.
- read(char cbuf[],int offset,int length)—将流中length个字符读取到字符数组cbuf中,cbuf中从offset位置开始
- ready()—流是否准备读取,读取缓冲区不为空或者底层输入流中可读取数据时返回true.
- close()—关闭流,释放相关资源.
案例
代码语言:javascript复制public class InputStreamDemo {
public static void main(String[] args) throws IOException {
String charsetName="UTF-8";
testOutputStreamWriter(charsetName);
testInputStreamReader(charsetName);
}
private static void testOutputStreamWriter(String charsetName) throws IOException {
char[] cbuf = new char[] {'h','e','l','l','o','w','o','r','l','d'};
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\java.txt"),charsetName);
osw.write("0123456789", 0, 8);
osw.write(cbuf, 1, 6);
osw.write('h');
osw.close();
}
private static void testInputStreamReader(String charsetName) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\java.txt"),charsetName);
int read = isr.read();
System.out.println("单个字符--------" (char)read);
char[] cbuf = new char[1024];
isr.read(cbuf, 0, 10);
System.out.println(new String(cbuf));
String encoding = isr.getEncoding();
System.out.println("解码方式--------" encoding);
isr.close();
}
}
运行结果:
单个字符——–0 1234567ell 解码方式——–UTF8
源码分析
1.InputStreamWriter源码分析
代码语言:javascript复制public class OutputStreamWriter extends Writer {
//负责编码的类StreamEncoder
private final StreamEncoder se;
//创建一个指定字节输出流和"指定"的字符编码名称的OutputStreamWriter流.
public OutputStreamWriter(OutputStream out, String charsetName)
throws UnsupportedEncodingException
{
super(out);
if (charsetName == null)
throw new NullPointerException("charsetName");
se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
}
//创建一个指定字节输出流和默认编码方式的OutputStreamWriter流.
public OutputStreamWriter(OutputStream out) {
super(out);
try {
se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
//创建一个指定字节输出流和"给定"字符编码方式的OutputStreamWriter流.
public OutputStreamWriter(OutputStream out, Charset cs) {
super(out);
if (cs == null)
throw new NullPointerException("charset");
se = StreamEncoder.forOutputStreamWriter(out, this, cs);
}
//创建一个指定字节输出流和"给定"编码器的OutputStreamWriter流.
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();
}
//刷新输出缓冲数据到底层字节流中
void flushBuffer() throws IOException {
se.flushBuffer();
}
//将单个字符写到流中
public void write(int c) throws IOException {
se.write(c);
}
//将字符数组cbuf中,off位置开始,len个字符写到流中
public void write(char cbuf[], int off, int len) throws IOException {
se.write(cbuf, off, len);
}
//将字符串中off位置开始,len个字符写到流中
public void write(String str, int off, int len) throws IOException {
se.write(str, off, len);
}
//刷新流
public void flush() throws IOException {
se.flush();
}
//关闭流,释放相关资源
public void close() throws IOException {
se.close();
}
}
2.InputStreamReader源码分析
代码语言:javascript复制public class InputStreamReader extends Reader {
//负责解码的类StreamDecoder
private final StreamDecoder sd;
//创建一个指定了底层字节输入流和默认字符编码方式的InputStreamReader流
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);
}
}
//创建一个指定了底层字节输入流和"指定"字符集编码方式的InputStreamReader流
public InputStreamReader(InputStream in, String charsetName)
throws UnsupportedEncodingException
{
super(in);
if (charsetName == null)
throw new NullPointerException("charsetName");
sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
}
//创建一个指定了底层 字节输入流和"给定"字符编码方式的InputStreamReader流.
public InputStreamReader(InputStream in, Charset cs) {
super(in);
if (cs == null)
throw new NullPointerException("charset");
sd = StreamDecoder.forInputStreamReader(in, this, cs);
}
//创建一个指定了底层字节输入流和"给定"字符集编码器的InputStreamReader流.
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();
}
//从InputStreamReader流中读取字符数据到字数数组cbuf中,cbuf中位置从offset开始,长度为length个字符
public int read(char cbuf[], int offset, int length) throws IOException {
return sd.read(cbuf, offset, length);
}
//流是否准备读取,读取缓冲区不为空或者底层输入流中可读取数据时返回true.
public boolean ready() throws IOException {
return sd.ready();
}
//关闭流,释放相关资源
public void close() throws IOException {
sd.close();
}
}
总结
InputStreamReader流和OutputStreamWriter流作为字节和字符转换的桥梁,需要知道字符是以指定的编码方式存储到文件中,同理读取文件的时候,通过相同的编码方式进行解码成字符,读取到内存或者程序中.其中”指定的编码方式”在创建流的时候需要指定,否则是默认的编码方式(GBK).
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/189439.html原文链接:https://javaforall.cn