异常
异常就是程序运行时发生的不正常情况,如打开一个不存在的文件,与错误不同(代码错误),异常一般分为两大类:
- Error:由于java虚拟机的限制而产生的程序错误,一般无法解决。如:JVM系统内部错误、资源耗尽等严重情况。
- Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理
Error和Exception包含如下: - Java采用抓抛模型catch-throw异常处理机制,将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁,易于维护。
- 异常对象的生成两种方式
1.由虚拟机自动生成:程序运行过程中,虚拟机检测到程序发生了问题,如果在当前代码中没有找到相应的处理程序,就会在后台自动创建一个对应异常类的实例对象并抛出——自动抛出
2.由开发人员手动创建:创建好的异常对象不抛出对程序没有任何影响,和创建一个普通对象一样
- 捕获异常
当一个方法抛出异常时,如果没有实现异常处理,会一直向上寻找异常解决方法,如果一个异常回到main()方法,并且main()也不处理,则程序运行终止。 - 选择处理异常
如果这些异常是运行时异常,则方法的调用者有3种选择:
(1)不理会这些声明,编译可以通过;
(2)使用try…catch处理异常;
(3)使用throws继续延迟处理
如果是非运行时异常,方法调用者有两种选择:
(1)使用try…catch处理异常;
(2)使用throws继续延迟处理,让编译先通过。
try——catch捕获异常
- try-catch语句
在try语句块中,放置可能出现异常的代码。在catch语句块中是对异常对象进行处理的代码。当try中的保护代码块发生异常时,如果catch块中声明了该异常,异常将会被传递到catch块中。 - 每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。
- 如果明确知道产生的是何种异常,可以用该异常类作为catch的参数;也可以用其父类作为catch的参数,但是参数不能是与已知异常无关的异常类,否则将不会执行
- try-catch-finally语句
try-catch-finally语句就是在try-catch语句的基础上,加上finally代码块,finally代码块是无论是否发生异常都会被执行
throw和throws
当程序没有使用try-catch语句捕获异常时,就需要用到throw和throws关键字
- throws关键字
throws关键字(必须在定义方法的时候使用),用于声明该方法可能会抛出的异常类型,一般用于不知道该怎么处理异常时,放任其不管,当有异常抛出时会中断该方法,而异常被抛到这个方法的调用者那里。
使用throws关键字明确指出了该方法可能抛出的异常。throws后面如果声明多个异常类型,之间可用“,”分隔 - throw关键字
当创建一个异常对象之后,可以使用throw关键字抛出异常对象。throw必须在方法体中使用。
手动抛出异常但是有时候有些错误在jvm看来不是错误,所以我们需要自己手动引发异常,这就是throw的作用,例如:1
2
3
4
5
6
7public void setAge(int age) throws Exception {
if(age<0){
Exception e = new ArithmeticException(“年龄不能为负”);
throw e;
}
this.age = age;
} - 注意重写方法不能抛出比被重写方法范围更大的异常类型:
1
2
3
4
5
6
7
8
9
10
11
12
13public class A {
public void methodA() throws IOException {
……
} }
public class B1 extends A {
public void methodA() throws FileNotFoundException {
……
} }
public class B2 extends A {
public void methodA() throws Exception { //报错,抛出的异常类型比父类异常类型大
……
} }人工抛出异常
Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要人工创建并抛出。 - 人工抛出异常,首先要生成异常类对象,然后通过throw语句实现抛出操作,注意,可抛出的异常必须是Throwable或其子类的实例。
- 自定义异常类
自定义异常类是包括人工抛出异常的自定义类:
1.一般地,用户自定义异常类都是RuntimeException的子类。
2.自定义异常类通常需要编写几个重载的构造器。
3.自定义的异常类对象通过throw抛出。
4.自定义异常最重要的是异常类的名字,当异常出现时,可以根据名字判断异常类型。
5.用户自己的异常类必须继承现有的异常类
java文件操作
流
- 输入流:即读取源中的数据,输出流:传送数据到目的地
- 字节输入流:InputStream抽象类的子类创建的流对象
InputStream类提供的read方法以字节为单位顺序地读取源中的数据,直到源的末尾或输入流被关闭 - 字节输出流:OutputStream抽象类的子类创建的流对象
OutputStream的write方法以字节为单位顺序地写文件,直到流被关闭 - 字符输入流:Reader抽象类的子类创建的流对象
- 字符输出流:Writer抽象类的子类创建的流对象
File类
File类是对文件和文件夹操作的一个类,它有以下几个功能:
- 创建文件/文件夹
- 删除文件/文件夹
- 查找文件/文件夹(判断是否存在)
- 获取文件/文件夹
- 遍历文件夹
- 获取文件大小
由于不同操作系统的分隔符可能不同,所以File类有以下成员变量用于表示分隔符: - 默认名称分隔符:File.separatorr,即”"
- 默认路径分隔符:File.pathSeparator,即”;”
File类的创建
File的构造方法有三种:
一个参数:其参数是文件的路径,创建File的对象,其参数表示的文件可以不存在;
两个参数:前者表示父路径,后者表示子路径,组合起来表示文件路径;
两个参数:前者表示父类文件,后者表示子类文件;
当我们直接打印File对象时,将会打印出file的路径,即传递的参数:
1 | File file1 = new File("D:/IDEA/FileMode/1.txt"); |
File类的方法
1.获取文件路径,名称,大小
- String getPath(); //获取文件路径
- String getName(); //获取文件名
- long length(); //获取文件大小
1
2
3
4
5
6File file = new File("D:/IDEA/FileMode/1.txt");
System.out.println(file.getAbsolutePath()); //D:\IDEA\FileMode\1.txt
System.out.println(file.getName()); //1.txt
System.out.println(file.getAbsoluteFile()); //D:\IDEA\FileMode\1.txt
System.out.println(file.getPath()); //D:\IDEA\FileMode\1.txt
System.out.println(file.length()); //15
2.判断文件类型及是否存在
- boolean exists(); //判断文件是否存在
- boolean isFile(); //判断文件是否位文件
- boolean isDirectory(); //判断文件是否为文件夹
1
2
3
4File file = new File("D:/IDEA/FileMode/1.txt");
System.out.println(file.exists()); //true
System.out.println(file.isFile()); //true
System.out.println(file.isDirectory()); //false
3.创建,删除文件/文件夹(路径中的后缀无效,默认为名称)
- boolean createNewFile(); //创建新文件
- boolean delete(); //删除文件/文件夹
- boolean mkdir(); //创建单级目录
- boolean mkdirs(); //创建单级目录或多级目录
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
27File file1 = new File("D:/javaTestFile/temp1.txt");
//创建文件
try{
if(!file1.exists()) file1.createNewFile();
}catch (IOException e){
System.out.println("文件创建失败");
}
//创建单级文件夹
File file2 = new File("D:/javaTestFile/temp2");
try {
if(!file2.exists()) file2.mkdirs();
}catch (NullPointerException e) {
System.out.println("创建目录失败");
}
//创建多级文件夹
File file3 = new File("D:/javaTestFile/temp3/temp3_1/temp3_2");
try {
if(!file3.exists()) file3.mkdirs();
}catch (NullPointerException e) {
System.out.println("创建目录失败");
}
//删除文件和文件夹
file1.delete();
file2.delete();
4.获取文件夹下所有文件及文件夹(路径必须为文件夹路径)
- String[] list(); //获取文件夹下所有文件和文件夹,返回字符串数组
- File[] listFiles(); //获取文件夹下所有文件和文件夹,返回文件数组
1
2
3
4
5
6
7
8
9
10File file = new File("D:/javaTestFile");
String list[] = file.list();
for(String s : list){
System.out.println(s);
}
File files[] = file.listFiles();
for(File f : files){
System.out.println(f.getName());
}
遍历多级目录查找目标文件
使用递归遍历目录即可,下面的代码演示了查找javaTestFile目录下的所有txt文件
1 | import java.io.File; |
FileFilter——文件过滤器
FileFilter,即文件过滤器,是java库中的一个接口,用于筛选文件,文件过滤器使用原理如下图所示:
使用方法为: - 创建子类实现FileFilter,重写accept方法定义过滤规则,然后将子类对象传递进listFile(FileFilterImpl ff)方法的参数中,示例如下: 1.实现FileFilter,重写accept的规则为查找txt文件1 | import java.io.FileFilter; |
1 | import java.io.File; |
1 | import java.io.File; |
RandomAccessFile——随机读写文件
RandomAccessFile即可以读取文件内容,也可以向文件中写入内容,它包含了一个记录指针,用以标记当前读写处的位置,它的每次操作都是在指针所在处,所以它可以直接跳到文件的任意位置来读写数据。
RandomAccessFile的创建
RandomAccessFile的构造方法有两个参数,第一个是文件,第二个是权限管理:“r” 只读;“rw” 可读可写;“rws” 可读可写,并要求对文件内容或元数据的每个更新都同步写入到底层设备;“rwd” 可读可写,并要求对文件内容每个更新都同步写入到底层设备。
1 | File file = new File(filePath); |
RandomAccessFile的方法及注意事项
RandomAccessFile常用的方法如下:
- RandomAccessFile的read()和write()方法,同其他文件操作类
- long getFilePointer(); //返回文件记录指针的当前位置
- void seek(long pos); //将文件记录指针定位到pos位置
注意事项: - 在seek方法中指针是从0~n-1的,所以当指针指向length,读取的值是-1
- 用了RandomAccessFile的read方法后,指针会往后移动一个字符,而readline后会移动到下一行的开头,也就是再read就是下一行的开头第一字符。
RandomAccessFile实现在任意位置写文件和读文件
1 | import java.io.File; |