[TOC]
异常概述和分类 概述:异常就是Java程序在运行过程中出现的错误。 异常的分类:
通过API查看Throwable所知在Java.Lang里面使用是不用导包的它是JAVA语言中所有错误或者异常的超类(父根类);
Error : 服务器宕机,数据库崩溃等
Exception : 可以接收程序编译和运行时候发生的异常,并且异常子类后缀都是Exception;
异常的继承体系: Throwable (超类)
Error
Exception
编译时候异常(静态): Java程序必须显示处理,否则程序就会发生错误,无法通过编译;
RuntimeException(重点动态赋值) : 无需显示处理,也可以和编译时异常一样处理;
Q:JVM默认是如何处理异常的? 答: main函数收到这个问题时,有两种处理方式:
a:自己将该问题处理然后继续运行;
b:自己没有针对的处理方式只有交给调用main的jvm来处理;有一个默认的异常处理机制,就将该异常进行处理. 并将该异常的名称,异常的信息以及异常出现的位置打印在了控制台上,同时将程序停止运行
编译期异常和运行期异常的区别:
Java中的异常被分为两大类:编译时异常和运行时异常
。
所有的RuntimeException类及其子类的实例被称为运行时异常,其他的异常就是编译时异常
编译时异常也叫做未雨绸缪异常
(在做某些事情的时候要做某些准备)
编译时异常:在编译某个程序的时候,有可能会有这样那样的事情发生,比如文件找不到,这样的异常就必须在编译的时候处理,如果不处理编译通不过;
运行时异常:就是程序员所犯得错误,需要回来修改代码;
(1)RuntimeException案例演示:1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class Demo1_Exception { public static void main (String[] args) { Demo d = new Demo(); int x = d.div(10 , 0 ); System.out.println(x); } } class Demo { public int div (int a,int b) { return a / b; } }
weiyigeek.top-
异常处理方式 描述:异常处理的几种方式如下:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 try { ... }catch ("异常类" "接收参数" ){ ... } try { }catch ("异常类" "接收参数" ){ }finally { } try { ... } finally { ... }
异常注意:
JDK7以后处理多个异常的方式及注意事项;
安卓客户端开发,如何处理异常?
try{…}catch(Exception e){…}
JavaEE服务端开发,一般都是底层开发从底层向上抛;
补充说明:
当程序报出异常的时候为了快速定位查找,一般从下向上查找;
世界上最真情的相依就是你在try我在catch,无论你发神马脾气,我都静静接受,默默处理
当通过try…catch语句将问题处理了,程序会继续执行;
Throwable常用方法 描述:Throwable的几个常见方法
a:getMessage() : 获取异常信息,返回字符串。
b:toString() : 获取异常类名和异常信息,返回字符串。
c:printStackTrace() : 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
基础语法:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.weiyigeek.exception;public class Demo1_Throwable { public static void main (String[] args) { try { System.out.println(1 /0 ); } catch (Exception e) { System.out.println("1." + e.getMessage()); System.out.println(e); e.printStackTrace(); } } }
throws关键字 描述:throws的方式处理异常 定义功能方法时,需要把出现的问题暴露出来让调用者去处理,那么就通过throws在方法上标识。 throws语法:1 2 3 4 5 6 7 8 9 public void exceptionDemo () throws Exception { if (regual){ ... }else { throw new Exception("抛出异常" ) } }
throws语句也需要注意编译时和运行时抛出错误:
编译时异常: 必须在方法上进行声明否则报错;并且异常抛出必须对其进行处理。
运行时异常: 在编译时候不进行异常处理,而是在程序执行时候才进行异常处理;(函数默认的,函数上可以不用加throw RuntimeException
声明);并且运行时异常的抛出可以处理也可以不处理;
throw的概述以及和throws的区别 描述:在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出;
throws和throw的区别:
a:throws
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
b:throw
用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
基础示例:1 2 3 4 5 6 7 8 public void Demo1 () throws Exception,RuntimeException { throw new Exception("方式1:异常对象" ); }
finally关键字 finally关键字的特点及作用: 作用:用于释放资源,在IO流操作和数据库操作中会见到 特点:被finally控制的语句体一定会执行,特殊情况在执行到finally之前jvm退出了(比如System.exit(0))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package com.weiyigeek.exception;public class Demo4_finally { public static void main (String[] args) { try { System.out.println(1 /0 ); } catch (Exception e) { System.out.println("除数不能为Zero" ); return ; } finally { System.out.println("在return返回前执行了,而如果在System.exit(0)后面则不会执行finally" ); } } }
面试题1:final,finally和finalize的区别?
final 可以修饰类,不能被继承;修饰方法,不能被重写;修饰变量,只能赋值一次
finally 是try语句中的一个语句体不能单独使用,用来释放资源
finalize 是一个方法当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
面试题2:如果catch里面有return语句,请问finally的代码还会执行吗?如果会请问是在return前还是return后? 答:是可以的比如看下面的使用案例,并且是在Return后执行并且(在finally没有加return情况下)不会影响return里面的值;
finally关键字特殊使用案例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package com.weiyigeek.exception;public class Demo5_finally { public static void main (String[] args) { System.out.println(extracted()); } public static String extracted () { int x = 10 ; try { x = 20 ; System.out.println(1 /0 ); return "try代码块中必须要有return语句: " + x; } catch (Exception e) { x = 30 ; return "catch代码块中也必须要有return语句:" + x; } finally { x = 40 ; } } }
执行结果:1 catch 代码块中也必须要有return 语句:30
自定义异常概述使用 描述:自定义异常通常是基础父类里面的方法,它可以通过异常来快速定位代码程序的问题;
继承自Exception
继承自RuntimeException
异常注意事项:
a:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(例如:父亲坏了儿子不能比父亲更坏
);
b:如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常;
c:如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try不能throws;
异常处理原则:如果该功能内部可以将问题处理,用try如果处理不了,交由调用者处理这是用throws区别:
后续程序需要继续运行就 try 关键字
后续程序不需要继续运行就 throws 关键字
如果JDK没有提供对应的异常,需要自定义异常。(要么继承Exception要么继承RuntimeException然后重新父类里面的构造方法即可
)
自定义异常基础示例:(重点)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.weiyigeek.exception;public class Demo6_CustomException { public static void main (String[] args) throws AgeOutOfBoundsException { try { Demo1(1024 ); } catch (Exception e) { System.out.println(e); System.out.println("错误的信息 : " +e.getMessage()); } } public static void Demo1 (int age) throws AgeOutOfBoundsException { if ( age > 0 && age <= 150 ){ System.out.println("您是一个正常的人类" ); }else { throw new AgeOutOfBoundsException("年龄出现异常" ); } } } class AgeOutOfBoundsException extends Exception { public AgeOutOfBoundsException () { super (); } public AgeOutOfBoundsException (String message) { super (message); } }
异常处理基础示例2:(直接输打印异常)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 package com.weiyigeek.exception;import java.math.BigDecimal;import java.math.BigInteger;import java.util.Scanner;public class Demo6_Example { public static void main (String[] args) { System.out.println("/***\n*** 二进制转换异常处理案例 ***\n***/" ); Scanner sc = new Scanner(System.in); System.out.print("请输入一个整数: " ); while (true ) { String line = sc.nextLine(); try { int num = Integer.parseInt(line); System.out.println(line+ "(Binary) = " +Integer.toBinaryString(num)); } catch (Exception e) { try { new BigInteger(line); System.out.println("输入错误,录入的是一个过大的整数,请重新输入:" ); } catch (Exception e2) { try { new BigDecimal(line); System.out.println("输入错误,录入的是一个小数,请重新输入:" ); } catch (Exception e3) { System.out.println("输入错误,您录入的是非法字符,请重新输入一个整数:" ); } } } } } } 请输入一个整数: 1111111111111111111 输入错误,录入的是一个过大的整数,请重新输入: abc 输入错误,您录入的是非法字符,请重新输入一个整数: 13.3 输入错误,录入的是一个小数,请重新输入: 255 255 (Binary) = 11111111
File类概述和使用 描述:File类是一个路径解析类存放文件路径或者文件夹路径;
路径分为绝对路径和相对路径区分:
绝对路径是一个固定的路径,从盘符开始
相对路径相对于某个位置,在eclipse下是指当前项目下在DOS下;
文件和目录路径名的抽象表示形式:1 2 3 4 5 c:\\Windows\\system32 /etc/passwd
基础使用:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 * File(String pathname): 根据一个路径得到File对象 * File(String parent, String child): 根据一个目录和一个子文件/目录得到File对象 * File(File parent, String child): 根据一个父File对象和一个子文件/目录得到File对象 * public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了 * public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了 * public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来 public boolean renameTo(File dest):把文件重命名为指定的文件路径 public boolean delete():删除文件或者文件夹 public boolean isDirectory():判断是否是目录 public boolean isFile():判断是否是文件 public boolean exists():判断是否存在 public boolean canRead():判断是否可读 public boolean canWrite():判断是否可写 public boolean isHidden():判断是否隐藏 public String getAbsolutePath():获取绝对路径 public String getPath():获取构造方法中传入的路径 public String getName():获取名称 public long length():获取长度。字节数(文件大小)) public long lastModified():获取最后一次的修改时间,毫秒值 public String[] list():获取指定目录下的所有文件或者文件夹的名称数组 public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组 Throws IOException
基础案例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 package com.weiyigeek.file;import java.io.File;import java.io.IOException;import java.sql.Date;import java.text.SimpleDateFormat;public class Demo1_FileConstruction { public static void main (String[] args) throws IOException { File f1 = new File("E:\\githubProject\\Study-Promgram\\update.sh" ); System.out.println("方式1:判断update.sh是否存在 : " + f1.exists()); String parent = "E:\\githubProject\\Study-Promgram" ; String child = "update.sh" ; File f2 = new File(parent,child); System.out.println("方式2:" + f2.exists()); File file = new File("E:\\githubProject\\Study-Promgram" ); String filename = "update.sh" ; File f3 = new File(file,filename); System.out.println("方式3:" + file.exists() + " - " + f3.exists()); File f4 = new File("E:\\" ,"FileClass.txt" ); boolean flag = f4.createNewFile(); String res = flag ? "文件创建成功" : "文件已经创建" ; System.out.println(res); File d1 = new File("E:\\CreateDirector" ); System.out.println("创建单个文件 :" + d1.mkdir()); File d2 = new File("E:\\CreateDirector\\Web\\WWW" ); System.out.println("创建单个文件 :" + d2.mkdirs()); File f5 = new File("E:\\FileClass.txt" ); File f6 = new File("E:\\CreateDirector\\Web\\WWW\\FileClassRename.txt" ); System.out.println("文件删除:" + f6.delete()); System.out.println("文件夹删除:" + d1.delete()); System.out.println("是否是文件: " + f5.isFile()); System.out.println("是否是文件夹: " + d2.isDirectory()); System.out.println("绝对路径:" + f2.getAbsolutePath()); System.out.println("Filel类实例化传入路径 : " + f2.getPath()); System.out.println("文件名称: " + f2.getName()); System.out.println("文件大写: " + f2.length()); Date d = new Date(f5.lastModified()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss" ); System.out.println(sdf.format(d)); File f7 = new File("F:/day19_video" ); String[] arr = f7.list(); for (String s : arr) { System.out.println(s); } File[] filearr = f7.listFiles(); for (File sf : filearr) { System.out.println(sf); } } }
执行结果:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 方式1 :判断update.sh是否存在 : true 方式2 :true 方式3 :true - true 文件已经创建 创建单个文件 :false 创建单个文件 :false 文件删除:false 文件夹删除:false 是否是文件: true 是否是文件夹: true 绝对路径:E:\githubProject\Study-Promgram\update.sh Filel类实例化传入路径 : E:\githubProject\Study-Promgram\update.sh 文件名称: update.sh 文件大写: 64 2019 年09 月29 日 17 :09 :18 19.14 _File类(File类的概述和构造方法).avi19.15 _File类(File类的创建功能).avi19.16 _File类(File类的重命名和删除功能).avi19.17 _File类(File类的判断功能).avi19.18 _File类(File类的获取功能).avi19.19 _File类(输出指定目录下指定后缀的文件名).avi19.20 _File类(文件名称过滤器的概述及使用).aviF:\day19_video\19.14 _File类(File类的概述和构造方法).avi F:\day19_video\19.15 _File类(File类的创建功能).avi F:\day19_video\19.16 _File类(File类的重命名和删除功能).avi F:\day19_video\19.17 _File类(File类的判断功能).avi F:\day19_video\19.18 _File类(File类的获取功能).avi F:\day19_video\19.19 _File类(输出指定目录下指定后缀的文件名).avi F:\day19_video\19.20 _File类(文件名称过滤器的概述及使用).avi
注意事项:
如果你创建文件或者文件夹忘了写盘符路径,那么默认在项目路径下。
重命名注意如果路径名相同,就是改名; 如果路径名不同,就是改名并剪切。
Java中的删除不走回收站,且要删除一个文件夹,请注意该文件夹内不能包含文件或者文件夹。
File类过滤器 描述:利用1 2 3 * public String[] list(FilenameFilter filter) * public File[] listFiles(FileFilter filter)
基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.weiyigeek.file;import java.io.File;import java.io.FilenameFilter;public class Demo2_filter { public static void main (String[] args) { File f1 = new File("F:/day19_video" ); File[] subFiles = f1.listFiles(); for (File file : subFiles) { if (file.isFile() && file.getName().endsWith(".avi" )){ System.out.println(file); } } String[] arr = f1.list(new FilenameFilter() { @Override public boolean accept (File dir, String name) { File file = new File(dir, name); return file.isFile() && file.getName().endsWith(".avi" ); } }); for (String str : arr) { System.out.println("满足条件的 :" + str); } } }
执行结果:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 F:\day19_video\19.14 _File类(File类的概述和构造方法).avi F:\day19_video\19.15 _File类(File类的创建功能).avi F:\day19_video\19.16 _File类(File类的重命名和删除功能).avi F:\day19_video\19.17 _File类(File类的判断功能).avi F:\day19_video\19.18 _File类(File类的获取功能).avi F:\day19_video\19.19 _File类(输出指定目录下指定后缀的文件名).avi F:\day19_video\19.20 _File类(文件名称过滤器的概述及使用).avi 满足条件的 :19.14 _File类(File类的概述和构造方法).avi 满足条件的 :19.15 _File类(File类的创建功能).avi 满足条件的 :19.16 _File类(File类的重命名和删除功能).avi 满足条件的 :19.17 _File类(File类的判断功能).avi 满足条件的 :19.18 _File类(File类的获取功能).avi 满足条件的 :19.19 _File类(输出指定目录下指定后缀的文件名).avi 满足条件的 :19.20 _File类(文件名称过滤器的概述及使用).avi
File类的使用 描述:实现File类的递归文件夹进行查找文件,从键盘接收一个文件夹路径打印出该文件下的所有的java文件名;
基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package com.weiyigeek.file;import java.io.File;import java.util.Scanner;public class Demo3_FileRecursion { public static void main (String[] args) { File path = getFile(); printTxt(path); } public static File getFile () { Scanner sc = new Scanner(System.in); System.out.println("请输入一个文件夹路径:" ); while (true ){ String path = sc.nextLine(); File dir = new File(path); if (!dir.exists()) { System.out.println("录入的文件夹路径不存在,请重新输入" ); }else if (dir.isFile()) { System.out.println("您录的是一个文件,请重新输入一个文件夹路径" ); }else { return dir; } } } public static void printTxt (File dir) { File[] subFiles = dir.listFiles(); for (File file : subFiles) { if (file.isFile() && file.getName().endsWith(".txt" )){ System.out.println(file); }else if (file.isDirectory()){ if (!file.getPath().endsWith("." )) { printTxt(file); } } } } }
File递归使用 基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 package com.weiyigeek.file;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.Scanner;public class Demo4_RecursionDemo { public static void main (String[] args) throws Exception { File dir = getPath(); printfFile(dir,0 ); } public static File getPath () { Scanner sc = new Scanner(System.in); System.out.print("请输入要统计/删除/拷贝文件夹得路径:" ); while (true ) { String lines = sc.nextLine(); File path = new File(lines); if (!path.exists()) { System.out.println("录入得文件夹路径不存在,请重新输入" ); }else if (path.isFile()){ System.out.println("您录入得是一个文件不是文件夹,请重新输入:" ); }else { return path; } } } public static long getFileSize (File dir) { long len = 0 ; File[] file = dir.listFiles(); for (File subFile : file) { if (subFile.isFile()){ len += subFile.length(); }else { len += getFileSize(subFile); } } return len; } public static void delFile (File dir) { File[] subFiles = dir.listFiles(); for (File file : subFiles) { if (file.isFile()){ file.delete(); }else { delFile(file); } } dir.delete(); } public static void copyFile (File src, File dest) throws IOException { File newDir = new File(dest, src.getName()); System.out.println(src.getName()); newDir.mkdir(); File[] subFiles = src.listFiles(); for (File file : subFiles) { if (file.isFile()) { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(newDir,file.getName()))); int ch; while ((ch = bis.read()) != -1 ) bos.write(ch); bis.close(); bos.close(); }else { copyFile(file, newDir); } } } public static void printfFile (File dir,int flag) { File[] subFiles = dir.listFiles(); for (File subFile: subFiles) { for (int i = 0 ; i <= flag; i++){ System.out.print("> " ); } System.out.println(subFile.getName()); if (subFile.isDirectory()) { printfFile(subFile,flag+1 ); } } } }
weiyigeek.top-
注意事项
递归recursion优缺点:
构造放不能使用递归调用
递归不一定存在返回值(可以有也可以没有)
IO流概述和使用 描述:IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式,用于操作流的类都在IO包中(java.io)
流按流向分为两种:输入流,输出流
。
流按操作类型分为两种:
字节流
: 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的(任意文件)
字符流
: 字符流只能操作纯字符数据,比较方便。
IO流常用父类:
字节流的抽象父类(不能够直接实例化的对象,必须采用其继承的子类对象):
InputStream 1 2 3 4 5 6 7 8 9 public abstract class InputStream extends Object implements Closeable FileInputStream("文件路径" ) FileReader
OutputStream1 2 3 4 5 6 7 8 9 public abstract class OutputStream extends Object implements Closeable, Flushable FileOutputStream("文件路径" ,追加(True/False)) FileWriter
字符流的抽象父类:
IO流常用的异常
IO程序书写:
使用前,导入IO包中的类
使用时,进行IO异常处理,内存与硬盘相关的关系需要进行异常的处理;
使用后,释放资源,对内存和磁盘操作后都需要进行释放资源;
IO流常用方法:1 2 3 4 5 6 7 8 9 10 11 - read () - available() - write() - write(byte[] b) - write(byte[] b, int off, int len) - close() 方法关闭打开的资源
实际案例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package com.weiyigeek.io;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo4_IO { public static void main (String[] args) throws IOException { try { FileInputStream fis = new FileInputStream("c:\\read.txt" ); int flag = 0 ; System.out.print("文件中读取到的字符: " ); while ((flag = fis.read()) != -1 ) { System.out.print(Character.toChars(flag)); } fis.close(); }catch (IOException e) { System.out.println(e.getMessage()); } try { FileOutputStream fos = new FileOutputStream("c:\\write.txt" ); for (int i = 32 ; i < 128 ; i++) { fos.write(i); } System.out.println("\nASCII码字符写入覆盖成功!" ); fos.close(); } catch (Exception e){ System.out.println(e.getMessage()); } try { FileOutputStream fos = new FileOutputStream("c:\\write.txt" , true ); fos.write('\r' ); fos.write('\n' ); fos.write('a' ); fos.write('p' ); fos.write('p' ); fos.write('e' ); fos.write('n' ); fos.write('d' ); System.out.println("追加Append写入成功!" ); fos.close(); } catch (Exception e) { System.out.println(e.getMessage()); } } } 文件中读取到的字符: abc ASCII码字符写入覆盖成功! 追加Append写入成功!
weiyigeek.top-
基础示例2:(拷贝图片、音频采用字节流)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package com.weiyigeek;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo5_IOunion { public static void main (String[] args) throws IOException { try { FileInputStream fis = new FileInputStream("F:\\IMG_2330.PNG" ); FileOutputStream fos = new FileOutputStream("F:\\IMG_2330.bak.png" ); int flag; while ((flag = fis.read()) != -1 ) { fos.write(flag); } System.out.print("示例1.输入流与输出流联合使用进行Copy图片的效果;" ); fis.close(); fos.close(); }catch (Exception e) { System.out.println(e.getMessage()); } try { FileInputStream fis = new FileInputStream("F:\\I2330.mp3" ); FileOutputStream fos = new FileOutputStream("F:\\2330.bak.mp3" ); byte [] count = new byte [fis.available()]; System.out.println("音频大小: " +fis.available()+" Byte" ); fis.read(count); fos.write(count); } catch (Exception e) { System.out.println(); }finally { System.out.println("示例2.一次性读取文件大的字节数到内存中,然后再内存中的字节数据写入到磁盘文件中" ); } } } 示例1 .输入流与输出流联合使用进行Copy图片的效果;图片大小: 69982 Byte 示例2 .一次性读取文件大的字节数到内存中,然后再内存中的字节数据写入到磁盘文件中
注意事项:
文件读取的结束标记是-1与C语言是00它们是不同的;
read()为什么返回是int而不是byte?
因为字节输入流可以操作任意类型的文件,比如图片音频等文件底层都是以二进制形式的存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到111111111;那么这11111111是byte类型的-1,我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收,如果11111111会在其前面补上24个0凑足4个字节,那么byte类型的-1就变成int类型的255了这样可以保证整个数据读完,而结束标记的-1就是int类型。 1 2 3 4 5 比如:一个文本的字节流表示 00010100 00100100 01000001 11111111(byte会导致提前结束读取) 0000000 10000001 11111110 11111111
IO字节流数组 描述:IO流采用字节数组可以更快更方便的进行文件的读取和写入,并且提高了大文件的读取和写入的效率; 基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.weiyigeek.io;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo4_IOarray { public static void main (String[] args) throws IOException { FileInputStream fis = new FileInputStream("C:\\demo.avi" ); FileOutputStream fos = new FileOutputStream("D:\\demo.avi" ); byte [] len = new byte [1024 * 8 ]; int length; while ((length = fis.read(len)) != -1 ) { fos.write(len, 0 , length); } fis.close(); fos.close(); } }
IO字节流缓存 描述:缓冲思想字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多(效率也比较高),这是加入了数组这样的缓冲区效果,java本身在设计的时候也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流
BufferedInputStream子类
内置了一个缓冲区(数组)从中读取一个字节时BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中返回给程序一个,程序再次读取时就不用找文件了, 直接从缓冲区中获取直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个; BufferedOutputStream子类
也内置了一个缓冲区(数组)程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 java.lang.Object java.io.InputStream java.io.FilterInputStream java.io.BufferedInputStream|BufferedOutputStream public class BufferedInputStream extends FilterInputStream //#实现一个缓冲输出流。通过设置这样的输出流,一个应用程序可以写字节到基本的输出流,而不必导致每个字节写入的底层系统的调用。 public class BufferedOutputStream extends FilterOutputStream //#公用方法 close () 方法 //#如果是带缓冲区的流对象的该方法具备刷新的功能会在关闭流之前会刷新一次缓存区,并且将缓冲区的字节全部都刷新到文件之上再关闭流释放资源的 ;flush()方法
基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.weiyigeek.io;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo5_IOBuffered { public static void main (String[] args) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\demo.txt" )); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\demo.bak.txt" )); int b; while ((b = bis.read()) != -1 ) { bos.write(b); } bis.close(); bos.close(); } }
weiyigeek.top-
补充:小数组的读写和带Buffered的读取哪个更快? 答:定义小数组如果是8192个字节大小和Buffered比较的话,定义小数组会略胜一筹,因为读和写操作的是同一个数组而Buffered操作的是两个数组
补充:close()与flush()方法的区别
close() 关闭流后不能继续读写
flush() 刷新缓冲区后可以继续读写
IO字节流中文处理 描述:字节流在读中文的时候有可能会读到半个中文会造成乱码(中文占用2Byte);由于字节流直接操作的字节,所以写出中文必须将字符串转换成字节数组
写出回车换行write("\r\n".getBytes());
基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package com.weiyigeek.io;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo6_IOrwchinese { public static void main (String[] args) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\demo.txt" )); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\chinese.txt" )); byte [] arr = new byte [bis.available()]; int size = bis.read(arr); System.out.println("文件大小: " + size + "B" ); System.out.println(new String(arr,0 ,size)); bos.write(arr); bos.write("\r\n" .getBytes()); bos.write("我和我的祖国一刻也不能分割!" .getBytes()); bis.close(); bos.close(); } } 文件大小: 17 B 我爱您,祖国!
weiyigeek.top-
IO字节流异常处理 描述:对于内存和磁盘的操作读写都需要对其进行异常处理,提高程序的健壮性; 原理:自动关闭IO流在try()中创建的流对象必须实现了AutoCloseable这个接口
,如果实现了在try后面的{}(读写代码)执行后就会自动调用流对象的close方法
将流关掉; (类似于PHP中操作文件fopen()的析构方法进行文件关闭处理
)
基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 package com.weiyigeek.io;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class Demo7_IOException { public static void main (String[] args) throws Exception { try ( FileInputStream fis = new FileInputStream("d:\\demo.txt" ); FileOutputStream fos = new FileOutputStream("d:\\chinese.txt" ); MyClose mc = new MyClose(fis,fos); ){ int n; while ((n = fis.read()) != -1 ) fos.write(n); } } public static void demo1 () throws FileNotFoundException, IOException { FileInputStream fis = null ; FileOutputStream fos = null ; try { fis = new FileInputStream("d:\\demo.txt" ); fos = new FileOutputStream("d:\\chinese.txt" ); int b; while ((b = fis.read()) != -1 ) fos.write(b); } finally { try { if (fis != null ){ try { fis.close(); } catch (IOException e) { fis = null ; e.printStackTrace(); } } } finally { if (fos != null ) fos.close(); } } } } class MyClose implements AutoCloseable { private FileInputStream fis = null ; private FileOutputStream fos = null ; public MyClose () { super (); } public MyClose (FileInputStream fis,FileOutputStream fos) { this .fis = fis; this .fos = fos; } @Override public void close () throws Exception { System.out.println("重写自动关闭流!采用AutoCloseable()接口" ); fis.close(); fos.close(); } } 重写自动关闭流!采用AutoCloseable()接口
JDK1.7及以上IO流自动关闭总结:
(1)需要关闭的资源必须实现Closeable或者AutoCloseable;查看JDK源码,Closeable继承自AutoCloseable,这两个接口中只有一个方法:void close() throws Exception;
(2)需要关闭的资源必须重写close()方法,方法中必须包含完整的资源关闭操作代码;
(3)调用写法:自动关闭功能属于try的增强特性,此时无需显式的书写资源关闭代码,try段代码执行完毕后,系统会自动调用资源的关闭方法关闭资源:
IO字节流图片加解密思路 描述:1Byte=8bit(11111111 - 127(max))将写出的字节异或一个密匙,解密的时候再次异或即可;
基础实例:(完整的采用处理异常的方法进行))1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 package com.weiyigeek.io;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo8_ImagesEncrpty { public static void main (String[] args) throws IOException { Byte secret = 127 ; System.out.println("1.图片加密中!" ); encryption(secret); System.out.println("2.图片解密中!" ); decrption(secret); } public static void encryption (Byte secretKey) throws IOException { FileInputStream fis = null ; FileOutputStream fos = null ; try { fis = new FileInputStream("d:\\qq.png" ); fos = new FileOutputStream("d:\\qq.encrpty.png" ); int count; while ((count = fis.read()) != -1 ) fos.write(count ^ secretKey); System.out.println("qq.png 加密完成!" ); }finally { if (fis != null ) fis.close(); if (fos != null ) fos.close(); } } public static void decrption (Byte secretKey) throws IOException { try ( FileInputStream fis = new FileInputStream("d:\\qq.encrpty.png" ); FileOutputStream fos = new FileOutputStream("d:\\qq.decrpty.png" ); ){ int count; while (( count = fis.read()) != -1 ) fos.write(count ^ secretKey); System.out.println("qq.encrpty.png 解密完成!" ); } } } 1 .图片加密中!qq.png 加密完成! 2 .图片解密中!qq.encrpty.png 解密完成!
weiyigeek.top-加密后的效果
IO字节流综合实例 需求1:在控制台录入文件的路径,将文件拷贝到当前项目下; 需求2:将键盘录入的数据拷贝到当前项目下文件中(上面的文件名称追加数据),键盘录入数据当遇到quit时就退出; 基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 package com.weiyigeek.io;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.Scanner;public class Demo9_IOSynthesize { public static void main (String[] args) throws IOException { File file = getFile(); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file.getName())); int b; while ((b = bis.read()) != -1 ) { bos.write(b); } bis.close(); bos.close(); Scanner sc = new Scanner(System.in); FileOutputStream fos = new FileOutputStream(file.getName(),true ); System.out.println("请输入数据:" ); while (true ) { String line = sc.nextLine(); if ("quit" .equals(line)) { break ; } fos.write(line.getBytes()); fos.write("\r\n" .getBytes()); } fos.close(); } public static File getFile () { Scanner sc = new Scanner(System.in); System.out.println("请输入一个文件路径:" ); while (true ) { String line = sc.nextLine(); File file = new File(line); if (!file.exists()) System.out.println("文件路径" + line + ", 文件不存在!请重写输入路径:" ); else if (file.isDirectory()) System.out.println("文件路径" + line + ", 是个文件夹!请重写输入路径:" ); else return file; } } } 文件路径, 文件不存在!请重写输入路径: d:\demo.txt 请输入数据: whoami? I'm WeiyiGeek! I Want to Study Java Paramgraming! quit' 我爱您,祖国!whoami? I'm WeiyiGeek! I Want to Study Java Paramgraming!
IO字符流介绍和使用 字符流是什么? 答:字符流是可以直接读写字符的IO流;使用过程字符流读取字符就要先读取到字节数据, 然后转为字符. 如果要写出字符需要把字符转为字节再写出(有了一个自动转换的功能)
为什么IO字符流可以按字节区分读取中文 答:这是因为编码表的功能
中文字符基本以负数的形式的体现的,所以比较好区分和划分,每一次发现一个负数也会将紧随其后的负数或者正数一起读取(即自动读取两个字节);
IO字符流类和方法 :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 java.lang.Object java.io.Reader java.io.InputStreamReader | OutputStreamWriter java.io.FileReader | FileWriter ---------------------------------------- public class FileReader extends InputStreamReader - read () public class FileWriter extends OutputStreamWriter - write() ---------------------------------------- java.lang.Object java.io.Reader java.io.BufferedReader | java.io.BufferedWriter public class BufferedReader extends Reader public class BufferedWriter extends Writer
基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package com.weiyigeek.io;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class Demo10_IOCharStream { public static void main (String[] args) throws IOException { FileReader fr = new FileReader("d:\\chinese.txt" ); int x; while ((x = fr.read()) != -1 ) System.out.print((char )x); fr.close(); FileWriter fw = new FileWriter("d:\\demo.txt" ,true ); fw.write("\r\n我和我的祖国一刻也不能分割!\r\n" ); fw.write(98 ); fw.close(); FileReader fr1 = new FileReader("d:\\chinese.txt" ); FileWriter fw1 = new FileWriter("d:\\demo.txt" ,true ); int ch; while ((ch = fr1.read()) != -1 ) fw1.write(ch); System.out.println("\n字符流拷贝完成!正在关闭IO流!" ); fr1.close(); fw1.close(); } } 我爱您,祖国! 字符流拷贝完成!正在关闭IO流! 我和我的祖国一刻也不能分割! b我爱您,祖国!
注意事项:
1.什么情况下使用字符流?什么情况下使用字节流?
字符流也可以拷贝文本文件但不推荐使用
. 因为读取时会把字节转为字符, 写出时还要把字符转回字节(效率问题);
[-]程序需要读取一段文本或者需要写出一段文本的时候(只读只写情况下)可以使用字符流
;优点:读取的时候是按照字符的大小读取的不会出现半个中文(乱码);写出的时候可以直接将字符串写出不用转换为字节数组。
[-]程序需要读取一段文本或者需要写出一段文本的时候可以使用字符
流;优点:读取的时候是按照字符的大小读取的不会出现半个中文;写出的时候可以直接将字符串写出不用转换为字节数组。
weiyigeek.top-
2.字符流是否可以拷贝非纯文本的文件?
不可以拷贝非纯文本的文件
;因为在读的时候会将字节转换为字符,在转换过程中,可能找不到对应的字符,就会用?代替,写出的时候会将字符转换成字节写出去如果是?,直接写出这样写出之后的文件就乱码无法正常打开;
IO字符流常规使用 1.自定义字符数组 描述:字符流不能向字节流一样可以获取字节个数,所以只能建立一个固定的小数组进行存放;
2.带缓冲的字符流
BufferedReader 的read()方法 读取字符时会一次读取若干字符到缓冲区, 然后逐个返回给程序, 降低读取文件的次数提高效率;
BufferedWriter 的write()方法 写出字符时会先写到缓冲区, 缓冲区写满时才会写到文件, 降低写文件的次数,提高效率;
BufferedReader 的readLine()方法 可以读取一行字符(不包含换行符号)以null标准结束
BufferedWriter 的newLine()方法 可以输出一个跨平台的换行符号”\r\n”
BufferedReader 的LineNumberReader 子类1 2 3 4 5 public class LineNumberReader extends BufferedReader void setLineNumber(int lineNumber) int getLineNumber()
基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 package com.weiyigeek.io;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class Demo11_IOCharCustom { public static void main (String[] args) throws IOException { customArray(); bufferRW(); System.out.println("3.字符流缓存区读取和写入一行到文件" ); BufferedReader br = new BufferedReader(new FileReader("d:\\chinese.txt" )); BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\demo.bak.txt" ,true )); bw.write("----------------------------------------------------" ); bw.newLine(); String lines; int count = 1 ; while ((lines = br.readLine()) != null ){ lines = "\t" + count++ + "." + lines; System.out.println(lines); bw.write(lines); bw.newLine(); } br.close(); bw.close(); } public static void bufferRW () throws FileNotFoundException, IOException { System.out.println("2.带缓冲的字符流" ); BufferedReader br = new BufferedReader(new FileReader("d:\\chinese.txt" )); BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\demo.bak.txt" ,true )); int ch; while ((ch = br.read()) != -1 ) { bw.write(ch); } br.close(); bw.close(); } public static void customArray () throws FileNotFoundException, IOException { System.out.println("1.自定义字符数组" ); FileReader fr = new FileReader("d:\\chinese.txt" ); FileWriter fw = new FileWriter("d:\\demo.txt" ); char [] arr = new char [1024 ]; int length; while ((length = fr.read(arr)) != -1 ) fw.write(arr,0 ,length); fr.close(); fw.close(); } }
weiyigeek.top-执行结果
基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 package com.weiyigeek.io;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.LineNumberReader;import java.util.ArrayList;public class Demo12_IOchardemo { public static void main (String[] args) throws IOException { reserse(); lnr(); } public static void reserse () throws IOException { BufferedReader br = new BufferedReader(new FileReader("d:\\chinese.txt" )); ArrayList<String> al = new ArrayList<>(); String lines; while ((lines = br.readLine()) != null ) al.add(lines); br.close(); BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\reverse.txt" )); for (int i = al.size() - 1 ; i >= 0 ; i--) { bw.write(al.get(i)); bw.newLine(); } bw.close(); } public static void lnr () throws FileNotFoundException, IOException { LineNumberReader lnr = new LineNumberReader(new FileReader("d:\\chinese.txt" )); String line; lnr.setLineNumber(1 ); while ((line = lnr.readLine()) != null ){ System.out.println(lnr.getLineNumber() + ":" + line); } lnr.close(); } }
注意事项:
newLine() 与 “\r\n”之间的关系?
bw.write(“\r\n”); //只支持windows系统
IO流类型转换 注意:UTF-8字符集编码一个中文字符占用3个字节,而GBK字符集编码一个中文字符占用2个字节; 描述:所以在输出内容时候由于默认编码表的不同,我们需要指定码表读取字符还可以指定码表写字符;
基础实例:1 2 3 4 5 6 7 8 9 10 11 12 java.lang.Object java.io.Reader | java.io.Writer java.io.InputStreamReader | java.io.OutputStreamReader public class InputStreamReader extends Reader //字节->字符//#FileWriter 是使用默认码表写出文件, 如果需要使用指定码表写出, 那么可以使用OutputStreamWriter (字节流,编码表) public class OutputStreamWriter extends Writer //字符->字节//#建议对其再次进行封装提高效率 BufferedReader(new InputStreamReader(new FileInputStream(""),CharsetName)) BufferedReader(new OutputStreamReader(new FileOutputStream("" ),CharsetName))
基础实例:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 package com.weiyigeek.io;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.UnsupportedEncodingException;import java.util.TreeMap;public class Demo13_IOtranstion { public static void main (String[] args) throws IOException { demo1(); demo2(); } public static void demo2 () throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("d:\\chinese.txt" ),"UTF-8" )); TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>(); int ch; while ((ch = br.read()) != -1 ) { char c = (char )ch; if (!tm.containsKey(c)){ tm.put(c, 1 ); }else { tm.put(c, tm.get(c) + 1 ); } } br.close(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:\\times.txt" ),"gbk" )); for (Character key : tm.keySet()) { switch (key) { case ' ' : bw.write("[空格]=" + tm.get(key)); System.out.println("[空格]=" + tm.get(key)); break ; case '\n' : bw.write("\\n=" + tm.get(key)); System.out.println("\\n=" + tm.get(key)); break ; case '\r' : bw.write("\\r=" + tm.get(key)); System.out.println("\\r=" + tm.get(key)); break ; default : bw.write(key + "=" + tm.get(key)); System.out.println(key + "=" + tm.get(key)); break ; } bw.newLine(); } bw.close(); } public static void demo1 () throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("d:\\chinese.txt" ),"utf-8" )); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:\\demoo.txt" ),"gbk" )); int ch; while ((ch = br.read()) != -1 ) bw.write(ch); br.close(); bw.close(); } } \n=2 \r=2 [空格]=3 !=3 '=1 ,=1 A=2 G=1 I=2 J=1 V=1 W=1 d=1 e=3 g=1 i=3 k=1 m=1 n=1 s=1 t=1 u=1 y=2 国=1 您=1 我=1 爱=1 祖=1
weiyigeek.top-IO转换原理
学习总结:
1.用BufferedReader读取GBK码表和UTF-8码表的字符
2.用BufferedWriter写出字符到GBK码表和UTF-8码表的文件中