1、字节流与字符流的区别
字节流处理单元为1个字节,操作字节和字节数组,而字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串。所以字符流是由Java虚拟机将字节转化为2个字节的Unicode字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点.
代码说明(以读取文件E:\tesst\test.txt 内容为例 test.txt)
字节流
import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class ReadTest { //1、定义缓冲区大小可以是1024的整数倍 private static final int SIZE = 1024; public static void main(String[] args) throws IOException { //创建流 File file = new File("E:\\test\\test.txt"); FileInputStream fis = new FileInputStream(file); byte []buf = new byte[SIZE]; int len = fis.read(buf); String result = new String(buf, 0, len);// 将字节数组转成字符串,而且是按照默认的编码表(GBK)进行解码。 System.out.println(result); //关闭资源 fis.close(); } }
字节流String类的String(byte[] bytes, int offset, int length)构造方法是通过使用平台的默认字符集(即GBK码表)解码指定的byte子数组,构造一个新的String
字符流
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class ReadTest { public static void main(String[] args) throws IOException{ // 1、创建字节流 File file = new File("E:\\test\\test.txt"); FileInputStream fis = new FileInputStream(file); // 2、建立字节向字符转换流。 InputStreamReader isr = new InputStreamReader(fis); int result = isr.read(); System.out.println((char)result); int result2 = isr.read(); System.out.println((char)result2); int result3 = isr.read(); System.out.println(result3); //3、关闭资源 fis.close(); isr.close(); } }
2、编码表
2.1编码表的由来
计算机只能识别二进制数据,早期由来是电信号来表示,为了方便应用计算机,让它可以识别各个国家的文字,就将各个国家的文字用数字来表示,并一一对应,形成一张表,这就是编码表。
2.2常见的编码表
常见的编码表有:
- ASCII:美国标准信息交换码,用一个字节的7位可以表示。
- ISO8859-1:拉丁码表或欧洲码表,用一个字节的8位表示。
- GB2312:中国的中文编码表。
- GBK:中国的中文编码表升级,融合了更多的中文文字符号。
- Unicode:国际标准码,融合了多种文字,所有文字都用两个字节来表示,Java语言使用的就是Unicode。
- UTF-8:最多用三个字节来表示一个字符。
2.3编码与解码
所谓编码就是字符串变成字节数组(String→byte[]),代表方法为 str.getBytes(charsetName);而所谓解码就是字节数组变成字符串(byte[]→String),代表方法为 new String(byte[], charsetName);。关于编码与解码,有一个结论,即由UTF-8编码,自然要通过UTF-8来解码;同理,由GBK来编码,自然也要通过GBK来解码,否则会出现乱码。
3、字符流
3.1字符流类的层次结构
3.1.1输入流
3.1.2输出流
3.2常用的字符流
BufferedReader、BufferedWriter、PrintWrite
3.2.1转换流InputStreamReader\OutputStreamWriter
InputStreamReader 将字节流转换为字符流。是字节流通向字符流的桥梁。OutputStreamWriter 将字节流转换为字符流。是字节流通向字符流的桥梁。如果不指定字符集编码,该解码过程将使用平台默认的字符编码,如:GBK。
例 在文件中写入数据然后读出数据最后打印读出的数据
package com.xyq.read; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class StreamConverter { public static void main(String[] args)throws IOException { writeTest(); readTest(); } public static void writeTest()throws IOException{ //1、创建流 File file = new File("tempFile\\test.txt"); FileOutputStream fos = new FileOutputStream(file); OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8"); //2、写出数据 osw.write("世界你好!"); //3、关闭资源 osw.close(); fos.close(); } public static void readTest()throws IOException{ //1、创建流 File file = new File("tempFile\\test.txt"); FileInputStream fis = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(fis, "utf-8"); //2、读出入数据 char []cbuf = new char[1024]; int len = isr.read(cbuf); String result = new String(cbuf, 0, len); System.out.println(result); //3、关闭资源 isr.close(); fis.close(); } }
3.2.2转换流的子类,用于操作字符文件的便捷类FileReader\FileWriter
package com.xyq.read; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class SubTransStreamTest { public static void main(String[] args)throws IOException { writeTest(); readTest(); } public static void writeTest() throws IOException{ //1、创建流 File file = new File("tempFile\\test.txt"); FileWriter fw = new FileWriter(file); //2、写出数据 fw.write("世界你好!"); //3、关闭资源 fw.close(); } public static void readTest()throws IOException{ //1、创建流 File file = new File("tempFile\\test.txt"); FileReader fr = new FileReader(file); //2、读入数据 char []cbuf = new char[1024]; int len = fr.read(cbuf); String result = new String(cbuf, 0, len); System.out.println(result); //3、关闭资源 fr.close(); } }
3.2.3缓冲流BufferedReader\BufferedWriter
例 在硬盘上,创建一个文件并写入一些文字数据,然后读取文字数据,最后打印读取的文字数据
package com.xyq.read; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class CharBufferedStreamTest { public static void main(String[] args)throws IOException { writeTest(); readTest(); } public static void writeTest()throws IOException{ //1、创建流 File file = new File("tempFile\\test.txt"); FileOutputStream fos = new FileOutputStream(file); OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8"); BufferedWriter bw = new BufferedWriter(osw); //2、写出数据 for(int i=0; i<3; i++){ bw.write(i + "世界你好!"); bw.newLine(); bw.flush(); } //3、关闭资源 bw.close(); osw.close(); fos.close(); } public static void readTest()throws IOException{ //1、创建流 File file = new File("tempFile\\test.txt"); FileInputStream fis = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(fis, "utf-8"); BufferedReader br = new BufferedReader(isr); //2、读入数据 String result = ""; while((result = br.readLine()) != null){ System.out.println(result); } //3、关闭资源 br.close(); isr.close(); fis.close(); } }
3.2.4PrintWrite
向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print 方法。它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。
与 PrintStream 类不同,如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,而不是每当正好输出换行符时才完成。这些方法使用平台自有的行分隔符概念,而不是换行符。
此类中的方法不会抛出 I/O 异常,尽管其某些构造方法可能抛出异常。客户端可能会查询调用 checkError() 是否出现错误。
printWrint常用APIpackage com.xyq.read; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class PrintStreamTest { public static void main(String[] args) { // printTest(); printAutoFlshTest(); printControllerTest(); } /** * 使用打印流写入到文件 */ public static void printTest(){ File file = null; PrintWriter out = null; try { //1、创建流 file = new File("tempFile\\test.txt"); //2、实例化printWriter打印对象,并开启自动刷新功能 out = new PrintWriter(file); //3、写入数据 out.println("你好 世界 !"); out.flush(); } catch (IOException e) { e.printStackTrace(); }finally { //4.关闭资源 if(out != null){ try { out.close(); } catch (Exception e) { e.printStackTrace(); } } } } /** * 使用自动刷新的打印流写入到文件 */ public static void printAutoFlshTest(){ File file = null; FileWriter fw = null; PrintWriter out = null; try { //1、创建流 file = new File("tempFile\\test.txt"); fw = new FileWriter(file); //2、实例化printWriter打印对象,并开启自动刷新功能 out = new PrintWriter(fw, true); //3、写入数据 //将数据写入到文件 //因为开启了自动刷新功能,所以println相当于以下执行了以下方法 //printWriter.write(String string);写入字符 //printWriter.newLine(); 换行 //printWriter.flsh(); 冲刷数据 out.println("我开启了PrintWriter的自动缓冲刷新功能"); out.println("我将要被写入到文件中,等待被读取"); } catch (IOException e) { e.printStackTrace(); }finally { //4.关闭资源 if(out != null){ try { out.close(); } catch (Exception e) { e.printStackTrace(); } } if(fw != null){ try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 读取文件内容,使用PrintWriter打印到控制台 */ public static void printControllerTest(){ File file = null; FileReader fr = null; BufferedReader in = null; PrintWriter out = null; try { //1、创建流 file = new File("tempFile\\test.txt"); fr = new FileReader(file); in = new BufferedReader(fr); //2、实例化printWriter打印对象,并开启自动刷新功能 out = new PrintWriter(System.out, true); //3、输出数据 String result = ""; while((result = in.readLine()) != null){ //将数据输出到控制台 //因为开启了自动刷新功能,所以println相当于以下执行了以下方法 //printWriter.write(String string);写入字符 //printWriter.newLine(); 换行 //printWriter.flsh(); 冲刷数据 out.println(result); } } catch (IOException e) { e.printStackTrace(); }finally { //4.关闭资源 if(out != null){ try { out.close(); } catch (Exception e) { e.printStackTrace(); } } if(in != null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if(fr != null){ try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
4、System类对IO的支持
package com.xyq.read; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class SystemIOTest { public static void main(String[] args) { BufferedReader bufr = null; BufferedWriter bufw = null; try { //1、读取键盘录入 System.out.println("请输入你的想要输入的信息"); bufr = new BufferedReader(new InputStreamReader(System.in)); //2、创建输出流 bufw = new BufferedWriter(new OutputStreamWriter(System.out)); //3、输出读取到的信息 String result = ""; while((result = bufr.readLine()) != null){ if("over".equals(result)){ System.out.println("输入结束"); break; } bufw.write(result);//写出数据 bufw.newLine();//换行 bufw.flush();//冲刷 } } catch (IOException e) { e.printStackTrace(); }finally { //4、关闭资源 if(bufw != null){ try { bufw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(bufr != null){ try { bufr.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }