java学习笔记:IO流之转换流InputStreamReader,OutputStreamWriter,编码,解码

java学习笔记:IO流之转换流InputStreamReader,OutputStreamWriter,编码,解码

 

 

五、转换流
转换流=字节流+编码表
1.转换流出现的原因:因为字节流操作字符文件的时候,可能会出现乱码问题。
2.字节流读数据可能出现的问题:字节流一次读取一个字节的方式读取带有汉字的文件是有问题的。因为你读取到一个字节后,就转为字符在控制台输出了,而汉字是由2个字节组成的,所以这里会出问题。
3.文件复制的时候,字节流读取一个字节,写入一个字节,这个没有出现问题,是因为最终底层会根据字节做拼接,得到汉字。
4.汉字存储的规则:左边的字节数据肯定是负数,右边的字节数据可能是负数,也可能是正数,大部分情况下是负数。
代码示例:
String s1 = "hello";
String s2 = "你好";
byte[] bys1 = s1.getBytes();//[104,101,108,111]
byte[] bys2 = s2.getBytes();//[-60,-29,-70,-61]
System.out.println(Arrays.toString(bys1));
System.out.println(Arrays.toString(bys2));
创建一个输出流后,如果文件不存在,它会创建一个文件。如果文件存在,它会把文件清空。因为BufferedInputStream和BufferedOutputStream不能共用同一个文件。


六、编码表概述和常见的码表
1.编码表:由字符和对应的数据组成的一张表。
2.常见的编码表
ASCII:一个字节的7位表示数据,美国标准码表
ISO-8859-1:欧洲码表,一个字节的8位表示数据,兼容ASCII
GB2312:中文码表,兼容ASCII
GBK:中文码表的升级版,更多中文字符,兼容ASCII
UTF-8:可变长度的字符编码,用1-3个字节表示数据,又叫万国码表,兼容ASCII。用在网页上可以统一页面中的中文简体、繁体和其他语言的显示。

3.乱码问题:针对同一个数据,采用的编码和解码的编码不一致造成的。
为了不出现乱码的问题,要保证编码和解码采用统一的编码表。

七、字符串中的编码、解码问题
1.编码:
public byte[] getBytes(String charsetName) throws UnSupportedEncodingException;//使用指定的字符集将此String编码为byte序列,并将结果存储到一个新的byte数组中。默认编码为GBK。
String::public byte[] getBytes();//使用平台默认的编码表来编码
2.解码
String::public String(byte[] bytes, String charsetName);//通过使用指定的charset解码指定的byte数组,构造一个新的String
String::public String(byte[] bytes);//使用平台默认的编码表来解码
3.代码示例:
String s = "苍老师";
byte[] bys = s.getBytes("UTF-8");//编码
System.out.println(Arrays.toString(bys));
String s2 = new String(bys, "UTF-8");//解码
System.out.println(s2);

八、转换流的编码、解码
1.转换流其实就是一个字符流
转换流=字节流+编码表

2.字符输出流OutputStreamWriter: 
public OutputStreamWriter(OutputStream out);//根据默认编码把字节流转换为字符流
public OutputStreamWriter(OutputStream out, String charsetName);//根据指定编码,把字节流数据转换为字符流
代码示例:
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "UTF-8");
osw.write("你好");//调用写数据的方法
osw.close();//释放资源

3.OutputStreamWriter写数据的方法
public void write(int c);//写一个字符
public void write(char[] cbuf);//写一个字符数组
public void write(char[] cbuf, int offSet, int len);//写一个字符数组的一部分
public void write(String str);//写一个字符串
public void write(String str, int offSet, int len);//写一个字符串的一部分
写完数据后,没有发现数据,为什么呢?因为需要手动刷缓冲。
字符流写数据需要手动刷新缓冲。void flush()刷新该流的缓冲。close()方法在关闭流之前,先做了刷新缓冲的动作。
1字符=2字节
文件中的数据存储的基本单位是字节。
代码示例:
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"), "UTF-8");
osw.write("我爱苍老师".toCharArray());//把字符串转成字符数组  String::char[] toCharArray() 将此字符串转换为一个新的字符数组
osw.write("我爱苍老师".toCharArray(), 0, 2);
osw.write("我爱苍老师");
osw.write("我爱苍老师", 0, 2);

4.字符输入流InputStreamReader
public InputStreamReader(InputStream in);//用默认的编码读数据
public InputStreamReader(InputStream in, String charsetName);//用指定的编码读数据
代码示例:
InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"), "UTF-8");
//读数据,一次读取一个字符数据
int ch;
while((ch = isr.read()) != -1){
  System.out.print((char)ch);
}
isr.close();//释放资源

5.InputStreamReader读数据的方法
public int read();//一次读取一个字符
public int read(char[] cbuf);//一次读取一个字符数组
代码示例:
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"), "UTF-8");
//方式1:一次读取一个字符
int by;
while((by = isr.read()) != -1){
  System.out.print((char)by);
}
//方式2:一次读取一个字符数组
char[] chs = new char[1024];
int len;
while((len = isr.read(chs)) != -1){
  System.out.print(new String(chs, 0, len));//String::public String(byte[] bytes, int offset, int length);
}
//释放资源
isr.close();

6.练习题:把当前项目目录下的StringDemo.java内容复制到当前项目目录下的copy.java中。
数据源:StringDemo.java  -->读数据-->字符流-->InputStreamReader
目的地:copy.java  -->写数据-->字符流-->OutputStreamWriter
//封装数据源
InputStreamReader isr = new InputStreamReader(new FileInputStream("StringDemo.java"));
//封装目的地
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("copy.java"));
//读写数据
//方式1:一次读写一个字符
int ch;
while((ch = isr.read()) != -1){
  osw.write(ch);
}
//方式2:一次读写一个字符数组
char[] chs = new char[1024];
int len;
while((len = isr.read(chs)) != -1){
  osw.write(chs, 0, len);
}
//释放资源
osw.close();
isr.close();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值