IO流04
A.编码
1)概述
public byte[] getBytes(Charset charset):将String类型转换成字节数组:编码
把能看懂的编写成了看不懂的数据
public String(byte[] bytes,String charsetName):将byle类型的数组转换成String类型:解码
把看不懂的编写成能看懂的字符串
举例
谍战片(发送端和接收端) 有个码本(字符----->值)
发送:三天后晚上9点行动
能看懂的数据--->看不懂的 : 编码
三天后晚上9点行动------>字节数组--->数值---->二进制数据
接收:
看不懂的升级----->能看懂的字符串
二进制数据---->十进制---->数值----->String类型的字符串:三天后晚上9点行动
import java.io.UnsupportedEncodingException; import java.util.Arrays; public class Demo01 { public static void main(String[] args) throws UnsupportedEncodingException { String s = "三天后晚上9点行动"; // 编码 // byte[] bys = s.getBytes();// 默认GBK 一个汉字两个字节 // [-56, -3, -52, -20, -70, -13, -51, -19, -55, -49, 57, -75, -29, -48, // -48, -74, -81] // byte[] bys = s.getBytes("GBK"); // [-56, -3, -52, -20, -70, -13, -51, -19, -55, -49, 57, -75, -29, -48, // -48, -74, -81] byte[] bys = s.getBytes("utf-8");// UTF-8 一个汉字三个字节 // [-28, -72, -119, -27, -92, -87, -27, -112, -114, -26, -103, -102, // -28, -72, -118, 57, -25, -126, -71, -24, -95, -116, -27, -118, -88] System.out.println(Arrays.toString(bys)); // 解码 // String ss = new String(bys) ;//gbk // String ss = new String(bys,"gbk") ; String ss = new String(bys, "utf-8"); // 如果编码不一致,会出现中文乱码 // 国内默认使用GBK System.out.println(ss);// 三天后晚上9点行动 } }
2)码表
编码解码的问题很简单:解码编码只要保证他们的编码格式一致,就不会出现乱码的情况!
B.字符输出流OutputStreamWriter
1)概述
上面的问题:字节流一次读取一个字节有问题,引入字符流
2)构造方法
public OutputStreamWriter(OutputStream out):默认编码:采用的格式:根据你的eclipse设置的默认格式
public OutputStreamWriter(OutputStream out,Charset cs):指定编码表
字符流=字节流 + 编码表 :将字节流转换成字符流
OutputStreamWriter(OutputStream out,Charset cs)
参数1:是一个抽象类:new FileOutputStream("路径名...","指定编码格式")
参数2:指定一个编码表:常用的两种格式:gbk/utf-8
一般情况:使用字符流:是字符输入流还是字符输出流:格式一律采用默认格式就可以了
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; public class Demo02 { public static void main(String[] args) throws IOException { // 创建字符输出流对象 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt")); // 使用指定编码格式进行对象的创建 // OutputStreamWriter osw = // new OutputStreamWriter(new FileOutputStream("osw.txt"),"utf - 8") ; // 写数据 osw.write("中国"); //关闭资源 osw.close(); } }
C.字符输入流OutputStreamReader
1)概述
读数据: Reader:抽象类------->InputStreamReader--->FileReader
2)构造方法
public InputStreamReader(InputStream in):默认的编码格式
public InputStreamReader(InputStream in,String charsetName):指定的编码格式
字符输入流= 字节输入流+ 编码表
import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class Demo03 { public static void main(String[] args) throws IOException { InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt")); // 读数据 一次一个字符 int ch = 0; while ((ch = isr.read()) != -1) { System.out.print((char)ch); } isr.close(); } }
D.字符转换输出流
1)方法
public void write(int c):写单个字符
public void write(char[] cbuf):写一个字符数组
public abstract void write(char[] cbuf, int off,int len):字符数组的一部分
public void write(String str):写字符串
public void write(String str, int off,int len):写一部分字符串
flush():刷新该流的缓冲!
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; public class Demo04 { public static void main(String[] args) throws IOException { // 创建字符转换输出流 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt")); osw.write('a'); // 单个单词 char[] ch = {'a', 'b', 'c'}; osw.write(ch); // 字符数组 osw.write(ch, 0, 1); // 字符数组一部分 osw.write("Java"); // 字符串 osw.write("HelloWorld", 0, 5); // 字符串一部分 // 刷新该流的缓冲 还可以继续写 osw.flush(); // 释放资源:先刷新再释放 osw.close(); } }
2)面试题
close()方法和flush()方法的区别?
close():关闭跟该流相关的资源,并且关闭之前,一定要刷新
防止出现没有写进去的情况,关闭之后不能在写数据了!
flush():刷新缓冲的流,刷新之后,还可以给文件中写数据
E.字符转换输入流
1)概述
字符输入流按照一个字符数组读取,其实就是字符转换输入流
2)方法
public int read():读取单个字符
public int read(char[] cbuf, int offset,int length):读取字符数组(读取的是实际长度)
import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class Demo05 { public static void main(String[] args) throws IOException { // 创建转换输入流对象 InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt")); // 读取一个字符 // int ch = isr.read(); // while (ch != -1) { // System.out.println((char)ch); // ch = isr.read(); // } // 或者 // int ch = 0; // while ((ch = isr.read()) != -1) { // System.out.println((char)ch); // } // 读取一个字符数组 char[] chs = new char[1024]; int len = 0; while ((len = isr.read(chs)) != -1) { System.out.println(new String(chs, 0, len)); } isr.close(); } }
F.转换流的应用
1) 转换流:字节流+编码(gbk)
非常麻烦:转换流的本身就比字节流代码的书写量大
引出一个新的写法
public FileReader(String fileName):建议使用
FileReader(File file)
2)需求
读取当前项目下的a.txt文件复制到项目下的b.txt中
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo06 { public static void main(String[] args) { // 创建输入流对象 FileReader fr = null; // 创建输出流对象 FileWriter fw = null; try { // 封装源文件 fr = new FileReader("a.txt"); // 封装目的文件 fw = new FileWriter("b.txt"); // 读取数据 char[] chs = new char[1024]; int len = 0; while ((len = fr.read(chs)) != -1) { fw.write(chs, 0, len); // 刷新一下 fw.flush(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { // 释放资源 fw.close(); fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }
3)注意
字符流只能赋值txt文件,不能赋值图片视频等