IO概述、异常、File文件类_DAY19
IO概述:
操作数据的工具
IO流,即数据流,数据像水流一样通过IO工具进行传输。
程序 <IO> 硬盘
绝对路径与相对路径
1:异常(理解)
(1)就是程序的非正常情况。
异常相关操作:
创建异常对象(JDK已定义的异常会自动创建对象,自定义异常需要手动创建)
抛出异常(JDK已有定义的异常会自动抛出异常,自定义异常需要手动抛出)
处理异常:
程序员在有异常抛出时,异常的处理方法有两种:(1)将异常捕获并处理(2)声明抛出异常
(2)异常的继承体系结构:
Throwable:
|--Error 严重的问题,不需要处理的。
|--Exception 非RuntimeException必须进行处理。两种方案,点击鼠标即可。
|--RuntimeException 运行时期异常,需要修正代码。
(3)jvm的默认处理方式:
默认情况下,jvm会采用默认处理方案:
把异常的全路径名称,原因,及位置等信息显示出来。
注意:
如果是jvm的默认处理方式,那么,它会在出问题的地方结束。
(4)我们自己的处理方案:
A:处理方式之一:使用捕获
try...catch...finally
基本格式:
try {
可能有问题的代码;
}catch(异常对象) {
对问题的处理;
}finally { //一定会执行的代码
释放资源;
}
变形格式:
try...catch
try...catch...catch
try...catch...catch...finally
try...finally
多异常处理方式:
分别捕获分别处理,每个try对应一个catch ( cn.itcast2.demo4)
package cn.itcast2; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /* * 多个异常的捕获处理: * 1:分别捕获分别处理,每个try对应一个catch */ public class Demo4 { public static void main(String[] args) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); try { Date parse = df.parse("2008-08-08"); System.out.println(parse); } catch (ParseException e) { System.out.println("您的日期格式有误,请换成2008-08-08的格式!"); } int a = 10; int b = 0; try { System.out.println(a/b); } catch (Exception e) { System.out.println("您的计算中,有数学错误,请更换数字"); } System.out.println("================"); } }
分别捕获分别处理,一个try对应所有catch (cn.itcast2.demo5) ,注意:大的异常不能在前边捕获
package cn.itcast2; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /* * 多个异常的捕获处理: * 2:分别捕获分别处理,一个try对应所有catch,注意:前边的异常一定要小于后边的异常 * 3:一次捕获共同处理,不能同时捕获大的异常与小的异常 */ public class Demo5 { public static void main(String[] args) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); int a = 10; int b = 0; //2:格式2 //报错,前边的异常不小于后边的异常 // try { // Date parse = df.parse("2008,08-08"); // System.out.println(parse); // System.out.println(a/b); // } catch (ParseException e) { // System.out.println("您的日期格式有误,请换成2008-08-08的格式!"); // } catch (ArithmeticException e) { // System.out.println("您的计算中,有数学错误,请更换数字"); // } try { Date parse = df.parse("2008,08-08"); System.out.println(parse); System.out.println(a/b); //前边的异常一定要小于后边的异常 } catch (ParseException e) { System.out.println("您的日期格式有误,请换成2008-08-08的格式!"); } catch (Exception e) { System.out.println("您的计算中,有数学错误,请更换数字"); } System.out.println("try后的代码继续执行..."); //格式3: try{ Date parse = df.parse("2008-08-08"); System.out.println(parse); System.out.println(a/b); }catch(ParseException|ArithmeticException e) { //一次捕获共同处理,不能同时捕获大的异常与小的异常 System.out.println(e); } System.out.println(true||false); System.out.println(true|false); } }
一次捕获共同处理
注意:不能同时捕获大的异常与小的异常
注意:
如果多个异常,有子父关系,父异常一定要放在最后。
如果多个异常,是平级关系,它们存在的位置没有顺序关系。
执行顺序:
在try里面的代码会按照从上往下执行,一旦发生问题,
就会产生一个异常对象,去和catch里面进行匹配。
有对应的匹配,就走对应的处理方案。
没有,就找父匹配,有就走对应的处理方案。
如果找不到,那么就由jvm采用默认处理方案。
JDK7的新特性:在处理多个平级的异常的时候
catch(ExceptionA | ExceptionB | ExceptionC ... e) {
}
B:异常处理方式之二:使用声明抛出
throws
* throws:用于声明函数抛出异常。用于函数声明。
* 多个异常可以同时声明抛出,用逗号分隔。 (cn.itcast2.demo7)
package cn.itcast2; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; /* * 异常处理方式:声明异常抛出 * throws:用于声明函数抛出异常。用于函数声明。 * 是异常对象的处理方式之一。 * 多个异常可以同时声明抛出,用逗号分隔。 */ public class Demo7 { public static void main(String[] args) { int a = 10,b=0; try { method(a,b); } catch (ArithmeticException e) { e.printStackTrace(); } System.err.println("--------------"); try { method2(a,b); } catch (ArithmeticException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } System.err.println("--------------"); } public static void method(int a,int b) throws ArithmeticException{ System.err.println(a/b); } public static void method2(int a,int b) throws ArithmeticException, ParseException{ //多个异常可以同时声明抛出,用逗号分隔 method(a,b); DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); df.parse("a"); } } /** 程序执行结果 java.lang.ArithmeticException: / by zero at cn1.Demo7.method(Demo7.java:35) at cn1.Demo7.main(Demo7.java:18) -------------- java.lang.ArithmeticException: / by zero at cn1.Demo7.method(Demo7.java:35) at cn1.Demo7.method2(Demo7.java:39) at cn1.Demo7.main(Demo7.java:25) -------------- */
(5)自定义异常
如果涉及其他需求,JDK没有提供相应的异常对象,则可以自己定义异常。
定义格式:继承Exception或者RuntimeException。同时需要带参的构造方法,用于接收异常信息。
public class MyException extends Exception{
public MyException(String message){
super(message);
}
}
例子:cn.itcast2.demo8 cn.itcast2.MyException.java
package cn.itcast2; /* * 自定义异常: * 补充java没有提供的异常类 */ public class Demo8 { public static void main(String[] args) { //规定,一个班最多只能有100个人。 int classNumber = 101; //方式一:捕获异常 if(classNumber>100) { try { throw new MyException("班级人数大于100了,不能大于100!");//手动抛出自定义异常类对象 } catch (MyException e) { System.err.println("======="); System.err.println(e.getMessage()+"........."); e.printStackTrace(); System.err.println("======="); } } System.err.println("-------------"); try { method(); } catch (MyException e) { e.printStackTrace(); } } //方式二:声明抛出异常 public static void method() throws MyException { //声明抛出异常 //规定,一个班最多只能有100个人。 int classNumber = 101; if(classNumber>100) { throw new MyException("班级人数大于100了,不能大于100!");//手动抛出自定义异常类对象 } System.err.println("-------------"); } }
package cn.itcast2; /* * 自定义异常:超过100就不行 */ public class MyException extends Exception { public MyException(String message) { super(message); } }
(6)面试题:
A:Exception和RuntimeException的区别?
Exception:分为编译期异常和运行期异常。编译期异常是必须处理的。否则,代码不能编译通过。
RuntimeException:运行期异常,不需要编写异常处理代码,但是可能需要修正程序参数或者逻辑代码。
B:throws和throw的区别?
throws:在方法声明上,后面跟的是异常类名。
throws声明后面如果是一个运行时期异常,调用者不需要处理。这种方式没有意义。
throws声明后面跟的是一个编译期异常,调用者是必须处理的。
throw:在方法体中,后面跟的是异常对象名。
throw后面如果抛出的是运行时期异常对象,那么方法上是不需要进行声明的。
throw后面如果抛出的是编译时期异常对象,那么,一般在方法声明上都是要用throws声明该方法有异常。
C:finally的面试题
a:final,finally,finalize的特点及区别?
final:最终的意思,可以修饰类,成员变量,成员方法
修饰类,类不能被继承
修饰变量,变量是常量
修饰方法,方法不能被重写
finally:是异常处理的一部分,用于释放资源。
一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了
finalize:是Object类的一个方法,用于垃圾回收
b:如果catch里面有return,请问finally里面的代码还执行吗?
如果执行,是在return前,还是后呢?
会执行,在前,确切的说在中间,先执行return的代码,再执行finally里面的代码,最后return
c:写一个程序,测试finally里面的操作对结果没有影响。
finally一般只用于释放资源。cn.itcast.demo9
D:jvm的默认处理方式? 打印,宕机
(7)对于异常,怎么选择呢?
A:能够自己处理的时候,尽量自己处理。
B:在方法里面尽量不要抛。
C:将来在实际开发中,我们会把不同的异常给出不同的界面进行显示给用户。
(8)子父关系中的异常处理?
class Fu {
public void show() throws Exception {
}
}
class Zi extends Fu {
public void show() throws RuntimeException {
}
}
class Demo {
public static void main(String[] args) {
}
}
子的重写方法中不能抛出比父更大的异常。
2:File(理解)
(1)因为硬盘上对数据的存储基本上都是以文件存在。为了方便对文件或者文件夹进行操作。
java就提供了一个类File供我们使用。本质上是对路径的封装。
(2)File类构造方法:
A:File file = new File("d:\\a.txt");
B:File file = new File("d:\\","a.txt");
C:File file = new File("d:");
File file2 = new File(file,"a.txt");
以上三种格式等价。
(3)File类的功能:
A:创建功能
创建文件:createNewFile()
创建文件夹:mkdir(),mkdirs()
例子:cn.itcast3.demo2
package cn.itcast3; import java.io.File; import java.io.IOException; /* * File类的普通方法: * 1:public boolean createNewFile() throws IOException 创建文件 * 2:public boolean mkdir() 创建文件夹 * 注意:现有文件夹,后有文件 * 3:public boolean mkdirs() 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。 将所有父目录全部创建。 */ public class Demo2 { public static void main(String[] args) throws IOException { //创建文件夹与文件对象 File dir = new File("z"); File file = new File("z/z.txt"); //2:创建文件夹z boolean mkdir = dir.mkdir(); System.out.println(mkdir); //1:创建文件z.text boolean createNewFile = file.createNewFile(); System.out.println(createNewFile); //层级创建文件 File dir2 = new File("c/a/d/e/w/d/f/t/z"); boolean mkdir2 = dir2.mkdirs(); System.out.println(mkdir2); } }
注意:仅仅根据后缀名并不能判断是文件还是文件夹。
B:删除功能
删除文件或者文件夹:delete()
注意:
A:删除一个带内容的目录,必须先删除内容,在删除目录。
B:java中的删除不走回收站。
C:判断功能
判断file是否存在:exists()
判断file是否是文件:isFile()
判断file是否是文件夹:isDirectory()
例子:cn.itcast3.demo3-myself.text
import java.io.File; import java.io.IOException; /* * File类的普通方法: * 1:public boolean delete() 文件可以直接删除,文件夹删除时,必须保证里边已经没有内容了 * 2:public boolean isHidden()测试此抽象路径名指定的文件是否是一个隐藏文件 * 3:public boolean isFile() 判断是否是文件 * 4:public boolean isDirectory() 判断是否是文件夹 * 5:public boolean exists() 测试此抽象路径名表示的文件或目录是否存在。 */ public class Demo3 { public static void main(String[] args) throws IOException { //创建文件夹 File dir = new File("b"); dir.mkdir(); //需要先创建文件夹,然后创建文件 File file = new File("b/b.txt"); file.createNewFile(); /* //先删除文件,再删除文件夹 System.out.println(file.delete()); System.out.println(dir.delete());*/ //是否是隐藏文件 System.out.println(file.isHidden()); //是否是文件 System.out.println(file.isFile()); //是否是文件夹 System.out.println(dir.isDirectory()); // 测试此抽象路径名表示的文件或目录是否存在。 System.out.println(file.exists()); } }
D:重名名功能
把旧名称改变为新名称:renameTo()
注意:路径问题。
重命名涉及两个File对象。
将File1重命名成File2
在同一目录下:
file2文件已经存在,重命名失败
file2文件不存在,重命名成功
在不同目录下:
file2文件已经存在,重命名失败
file2文件不存在,剪切成功
例子:cn.itcast3.demo4
package cn.itcast3; import java.io.File; /* * File类的普通方法: * public boolean renameTo(File dest) 同目录:重命名/不同目录:剪切加重命名 */ public class Demo4 { public static void main(String[] args) { File file = new File("a.txt"); File file2 = new File("b.txt"); File file3 = new File("d/c.txt"); boolean renameTo = file.renameTo(file2); System.out.println(renameTo); boolean renameTo2 = file2.renameTo(file3); System.out.println(renameTo2); } }
E:获取功能
基本获取
获取绝对路径:getAbsolutePath()
获取相对路径:getPath()
获取名称:getName()
获取大小:length() //英文字母1个字节,中文字母两个字节
获取最后修改时间:lastModified()
例子:cn.itcast3.demo5
package cn.itcast3; import java.io.File; import java.util.Date; /* * File类的普通方法: * 1:public String getAbsolutePath() : 返回此抽象路径名的绝对路径名字符串。 * 2:public String getPath(): 将此抽象路径名转换为一个路径名字符串。 * 3:public String getParent():返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。 * 4:public File getParentFile():返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。 * 5:public String getName():返回由此抽象路径名表示的文件或目录的名称。 * 6:public long length() 返回:文件存储内容的长度 * 7:public long lastModified():返回上一次修改时间毫秒值 */ public class Demo5 { public static void main(String[] args) { File file = new File("a.txt"); File file2 = new File("D:/Lesson/JAVA/JAVA基础/北京/150315/day19/code/day19/a.txt"); //1 System.out.println(file.getAbsolutePath()); System.out.println(file2.getAbsolutePath()); System.out.println("==========="); //2 System.out.println(file.getPath()); System.out.println(file2.getPath()); System.out.println("==========="); //3 String p = file.getParent(); System.out.println(p); String p2 = file2.getParent(); System.out.println(p2); System.out.println("==========="); //4 File pFile = file.getParentFile(); System.out.println(pFile); File pFile2 = file2.getParentFile(); System.out.println(pFile2); System.out.println("==========="); //5 String name = file.getName(); System.out.println(name); String name2 = file2.getName(); System.out.println(name2); System.out.println("==========="); //6 System.out.println(file.length()); //7 System.out.println(file.lastModified());//返回毫秒值1428829519158L System.out.println(new Date(file.lastModified()));//返回日期格式 } }
高级获取
获取指定目录下所有文件或者文件夹的名称数组:list()
获取指定目录下所有文件或者文件夹的File数组:listFiles()
返回所有盘符:listRoots()
例子1:cn.itcast3.demo6
package cn.itcast3; import java.io.File; import java.util.Arrays; /* * 文件高级获取: * 1:public static File[] listRoots() 获取所有盘符的文件对象 * 2:public String[] list() 这些字符串指定此抽象路径名表示的目录中的文件和目录。即该File下的所有文件及目录(字符串)。 * 3:public File[] listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。 即File下的所有文件及目录(File对象)。 */ public class Demo6 { public static void main(String[] args) { //1: File[] listRoots = File.listRoots(); System.out.println(Arrays.toString(listRoots)); //2: File dir = new File("src/cn/itcast"); String[] list = dir.list(); System.out.println(Arrays.toString(list)); //3: File[] listFiles = dir.listFiles(); System.out.println(Arrays.toString(listFiles)); for (File file : listFiles) { System.out.println(file.getName()); } } }
例子2:cn.itcast3.demo7:获取src\cn\itcast目录下所有.java结尾的文件(注意是文件 ,不是文件夹)
package cn.itcast3; import java.io.File; /* * 获取src\cn\itcast目录下所有.java结尾的文件 */ public class Demo7 { public static void main(String[] args) { //创建文件对象,表示指定的文件夹 File dir = new File("src/cn/itcast"); //方法一:(如果有文件夹是.java结尾的,则不能过滤该文件夹) // //获取该文件夹下的所有File对象字符串表现(文件,文件夹) // String[] list = dir.list(); // //获取该数组中的每一个元素 // for (String fileordir : list) { // boolean endsWith = fileordir.endsWith(".java"); // if(endsWith) { // System.out.println(fileordir); // } // } //方法二: //获取该文件夹下的所有File对象对象表现(文件,文件夹) File[] listFiles = dir.listFiles(); //获取该数组中的每一个元素 for (File fileordir : listFiles) { //先判断是否为文件 if(fileordir.isFile()) { boolean endsWith = fileordir.getName().endsWith(".java"); if(endsWith) { System.out.println(fileordir.getName()); } } } } }
文件过滤器:
接口 FilenameFilter 重写accept()方法
方式1,定义类实现FilenameFilter,然后用file.list(该类的实例对象)
方式2,匿名内部类
例子:cn.itcast3.demo8
package cn.itcast3; import java.io.File; import java.io.FilenameFilter; import java.util.Arrays; /* * File的方法: * public String[] list(FilenameFilter filter) * public File[] listFiles(FilenameFilter filter) * // 3:public File(File parent,String child) * 文件过滤器 * FilenameFilter: * boolean accept(File dir, String name) 将list/listFiles方法所在目录下所有的File对象都判断一次是否符合条件。符合条件返回true,不符合,返回false * * 获取src\cn\itcast目录下所有.java结尾的文件,要求使用过滤器 */ public class Demo8 { public static void main(String[] args) { //创建文件对象,表示指定的文件夹 File dir = new File("src/cn/itcast"); //获取该文件夹下的所有符合条件的File对象字符串表现(文件,文件夹) String[] list = dir.list(new FilenameFilter(){ //匿名内部类 @Override public boolean accept(File dir, String name) { File thisFile = new File(dir,name); if(thisFile.isFile()){ if(name.endsWith(".java")) { return true; } } return false; }}); System.out.println(Arrays.toString(list)); } }
---------------------------------------------------------------------------------------------------------------
例子程序:
1、返回某文件夹下所有以java结尾的文件
a)使用list方法
b)使用listFiles方法
c)使用list方法加文件过滤器
d)使用listFiles方法加文件过滤器
import java.io.File; import java.io.FilenameFilter; import java.util.Arrays; /** * 7:返回某文件夹下所有以java结尾的文件。 * a)使用list方法 * b)使用listFiles方法 * c)使用list方法加文件过滤器 * d)使用listFiles方法加文件过滤器 */ public class Test7 { public static void main(String[] args) { //a)使用list方法 (不能判断是文件还是文件夹) /* File file=new File("src/cn1"); String[] strings=file.list(); for(String s:strings){ if(s.endsWith(".java")){ System.out.println(s); } }*/ //使用listFiles方法 /* File file = new File("src/cn1"); File[] files = file.listFiles(); for (File f : files) { if (f.isFile()) { if(f.getName().endsWith(".java")){ System.out.println(f.getName()); } } }*/ //c)使用list方法加文件过滤器 /* File file=new File("src/cn1"); String[] strings=file.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { File file1=new File(dir,name); if(file1.isFile()){ if(file1.getName().endsWith(".java")){ return true; } } return false; } }); System.out.println(Arrays.toString(strings));*/ //d)使用listFiles方法加文件过滤器 /*File file=new File("src/cn1"); File[] files=file.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { File file1=new File(dir,name); if(file1.isFile()){ if(file1.getName().endsWith(".java")){ return true; } } return false; } }); for(File f:files){ System.out.println(f.getName()); }*/ } }
2、完成一个文件的创建,判断,删除。
import java.io.File; import java.io.IOException; /** * 3:完成一个文件的创建,判断,删除。 */ public class Test3 { public static void main(String[] args) throws IOException { File file=new File("src/cn2/a.test"); //文件的创建 file.createNewFile(); //判断 System.out.println(file.isFile()); System.out.println(file.isDirectory()); //删除 file.delete(); } }
3、完成文件的创建、重命名、删除。
import java.io.File; import java.io.IOException; /** * 5:完成文件的创建、重命名、删除。 */ public class Test5 { public static void main(String[] args) throws IOException { //文件的创建 File file=new File("d.txt"); file.createNewFile(); //重命名 File file1=new File("src/cn1/e.txt"); file.renameTo(file1); //删除 file1.delete(); } }
4、完成多级目录的创建。
import java.io.File; import java.io.IOException; /** * 6:完成多级目录的创建。 */ public class Test6 { public static void main(String[] args) throws IOException { File dir=new File("src/a/b/c/d/e"); dir.mkdirs(); File file=new File("src/a/a.txt"); file.createNewFile(); } }