在 I/O 操作中存在的编码
涉及编码的地方一般都在从字符到字节或者从字节到字符的转换上。
Reader 类是Java 中读字符的父类,而 InputStream 类是读字节的父类,InputStreamReader 类就是关联字节到字符的桥梁,它负责在 I/O 中处理读取字节到字符的转换。
写的情况类似,字符的父类是 Writer,写字节的父类是 OutputStream,通过 OutputStreamWriter 转换字符到字节。
书上用的是以前的 老Java 版本,我改成了适合现在大多用的 。
import java.io.*;
import java.nio.charset.*;
//写I/O 主要是从读写数据源到数据的方式。主要涉及了包装模式,包括装饰器模式和适配器模式。
public class IOTest {
public IOTest() {
}
public static void main(String args[]){
charToByte();
byteToChar();
}
/*
*通过修改Charset.forName()中的值,观察输出结果的不同
**/
public static void charToByte(){
String fileName = "1.txt";
try(FileOutputStream outputStream = new FileOutputStream(fileName)){
//写字符转换成字节流
OutputStreamWriter writer = new OutputStreamWriter(outputStream,Charset.forName("GBK"));
String content = "hello,world 你好,世界";
writer.write(content);
writer.close();
}catch(IndexOutOfBoundsException | IOException e ){
e.printStackTrace();
}
}
//读取字节转换成字符
public static void byteToChar(){
String fileName = "1.txt";
try(FileInputStream inputStream = new FileInputStream(fileName)){
InputStreamReader reader = new InputStreamReader(inputStream,Charset.forName("GBK"));
StringBuffer buffer = new StringBuffer();
char[] buf = new char[64];
int count = 0;
while((count=reader.read(buf))!= -1)
buffer.append(buf,0,count);
reader.close();
System.out.println(buffer.toString());
}catch( IndexOutOfBoundsException | IOException e){
e.printStackTrace();
}
}
}
这里有一个Java 9 API 可以看下。
在内存中操作的编码
在内存中进行字符到字节的数据类型转化。在Java 中用 String 表示字符串,String 类就提供了转换到字节的方法,也支持将字节转换为字符串的构造函数,
具体的可以查看上面的API
String s = "这是一段字符串";
//getBytes() 提供了一系列重载方法
//Using the platform's default charset
byte[] b = s.getBytes();
//Using given charset
byte[] b2 = s.getBytes(java.nio.charset.Charset.forName("UTF-8"));
//字节转换为字符串的构造函数
//Using the platform's default charset
String s1 = new String(b);
//Using given charset
String s2 = new String(b2,java.nio.charset.Charset.forName("UTF-8"));
Charset 类提供了public final CharBuffer decode(ByteBuffer bb)
和public final ByteBuffer encode(CharBuffer cb)
还有一个重载的public final ByteBuffer encode(String str)
。编码与解码都在同一个类中完成,通过 forName() 设置编解码字符集,这样更容易统一编码格式。
如果你觉得我的文章对你有所帮助的话,欢迎关注我的公众号。赞!
认认真真学习,做思想的产出者,而不是文字的搬运工。错误之处,还望指出!