文章目录
一、转换流
转换流是InputStreamReader、OutputStreamWriter,他们的父类分别是Reader、Writer。转换流的作用就是将字节按照指定的编码规则进行解码或编码。
1、字符编码和字符集
字符编码:
计算机中存储的信息都是二进制的,而我们见到的文字等都是二进制数转换之后的结果。按照这种规则,将字符存储到计算机中,称之为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称之为解码。编码和解码要是同一种规则,才会正常显示,不然会乱码。
编码:字符 --> 字节
解码:字节 --> 字符
- 字符编码:就是一套自然语言的字符与二进制数之间的对应规则关系。
字符集:
- 字符集:也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。
常见字符集:Unicode字符集、GBK字符集、ACSII字符集
ASCII字符集是最基础的编码,正数一个字节存储0-127个字符。
GBK字符集,GB(国标),用2个字节存储汉字。有GB2312、GBK、GB18030存储的汉字从少到多。各个编码一个字存储的字节不同。
Unicode字符集,其中UTF-8通用切常用字符集,一个汉字3个字节。
2、InputStreamReader 类
父类为Reader
抽象类,拥有父类所有的共性方法。
java.io.InputStreamReader
可以读取以该文本的编码规则读取该文本的内容,以达到正确读取该文本,不出现乱码情况。
读取的字节,以某种编码规则进行解码或编码。
构造方法
一共4个
public InputStreamReader(InputStream in)
创建一个使用系统默认字符编码的InputStreamReaderpublic InputStreamReader(InputStream in,String charsetName) throws UnsupportedEncodingException
创建一个指定字符集的InputStreamReader (参数charsetName不区分大小写)
public class InReaderTest {
public static void main(String[] args) throws IOException {
read_utf_8();
read_gbk();
}
public static void read_utf_8() throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("utf_8.txt"),"utf-8");
char[] ch = new char[1024];
int len;
while ((len = inputStreamReader.read(ch)) != -1){
System.out.println(new String(ch,0,len));
}
}
// 以gbk的形式读取gbk编码的文本,然后解析之后向控制台输出系统默认的utf-8编码的文本
public static void read_gbk() throws IOException{
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("gbk.txt"),"GBK");
char[] ch = new char[1024];
int len;
while ((len = inputStreamReader.read(ch)) != -1){
System.out.println(new String(ch,0,len));
}
}
}
3、OutputStreamWriter 类
父类为Writer
抽象类,拥有父类所有的共性方法。
java.io.InputStreamWriter
以指定的编码规则,编码文本到硬盘文件中。
写入的字节,以某种编码规则进行解码或编码。
构造方法
一共4个
public OutputStreamWriter(OutputStream out)
创建一个使用系统默认字符编码的OutputStreamWriterpublic OutputStreamWriter(OutputStream out,String charsetName) throws UnsupportedEncodingException
创建一个指定字符集的OutputStreamWriter (参数charsetName不区分大小写)
public class OutWriterTest {
public static void main(String[] args) throws IOException {
write_utf_8();
write_gbk();
}
public static void write_utf_8() throws IOException {
// 不指定编码,默认为UTF-8
//OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("utf_8.txt"));
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("utf_8.txt"),"utf-8");
outputStreamWriter.write("你好我是utf-8编码");
outputStreamWriter.flush();
outputStreamWriter.close();
}
public static void write_gbk() throws IOException{
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"GBK");
outputStreamWriter.write("你好我是GBK编码");
outputStreamWriter.flush();
outputStreamWriter.close();
}
}
UTF-8一个中文3个字节,ASCII码里的符号都是一个字节;GBK一个中文2个字节,ASCII码里的符号都是一个字节
练习:转换文件编码
将GBK编码的文本文件,转换成UTF-8编码的文本文件
public class TransTest {
public static void main(String[] args) throws IOException {
trans();
}
private static void trans() throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("gbk.txt"),"GBK");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("gbkToutf-8.txt"),"utf-8");
char[] ch = new char[1024];
int len = 0; // 读取到的有效字节个数
while ((len = inputStreamReader.read(ch)) != -1){
outputStreamWriter.write(ch,0,len);
outputStreamWriter.flush();
}
outputStreamWriter.close();
inputStreamReader.close();
}
}
二、IO流的异常捕获
1、JDK 7之前使用try catch finally捕获异常
public class Test {
public static void main(String[] args) {
// 因为在try代码块中定义输出流变量,finally代码块不能使用try代码块中的变量,作用域问题,因此提高变量作用域,代码块外定义,又因为在外定义有需要赋初始值,所以赋值null
FileOutputStream fileOutputStream = null;
try{
fileOutputStream = new FileOutputStream("a.txt");
fileOutputStream.write(48);
}catch (IOException e){
System.out.println("输出流IO异常");
}finally {
// 判断输出流是否为null,如果不判断如果为null,会报出异常NullPointerException
if(fileOutputStream != null){
try{
fileOutputStream.close();
}catch (IOException e){
System.out.println("Close的IO异常");
}
}
}
}
}
2、JDK 7捕获异常新特性
public class CatchTest {
public static void main(String[] args) {
// try() 括号中定义流,当流有异常会自动释放
try(FileOutputStream fileOutputStream = new FileOutputStream("a.txt")){
fileOutputStream.write(48);
}catch (IOException e){
System.out.println("输出流IO异常");
}
}
}
3、JDK 9捕获异常新特性
public class CatchTest {
public static void main(String[] args) throws IOException{
FileOutputStream fileOutputStream = new FileOutputStream("a.txt");
try(fileOutputStream){
fileOutputStream.write(48);
}catch (IOException e){
System.out.println("输出流IO异常");
}
}
}