在java编程语言当中,使用io流需要导入
(import java.io.*;)
在使用io流时需要处理io异常,这种异常称为编译时异常,即处理是否存在文件,是否关闭流等等操作。
-
1.throws
-
2.try{}catch(){}finally{}
-
3.try()catch(){}
-
在JDK7之前,对于IO流异常处理有两种方式: 本例使用缓冲流示例:
throws&try{}catch{}finally{}
throws方法抛出:
public class ThrowsTest {
/*
* 示例: BufferInputStream & BufferOutStream;
*/
public static void main(String[] args) throws IOException{
File file = new File("f:\\bb\\ThrowsTest.txt");
/*
* 此时存在异常 需要处理 :Unhandled exception type FileNotFoundException
* 文件是否存在的异常
*/
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(file));
//创建一个字节数组:
byte[] b = new byte[] {65,66,67,68,69,70};
/*
* write & close
* 此时存在异常:Unhandled exception type IOException
* 是否已经处理io异常
*
*/
fos.write(b);
fos.close();
}
上述代码可以看出,通过throws可以将异处理,再不出现其他异常的情况下会将代码成功写入到指定的文件当中;
但throws方法其实在处理IO流异常可能会出现资源不能关闭的情况,即close()方法不能执行,导致资源不能释放,资源会存在丢失的情况。
如下代码所示:可以看出抛出FileNotFoundException的异常,但是资源未被关闭。
public class ThrowsTest2 {
public static void main(String[] args) throws IOException{
File file2 = new File("f:\\bb\\ThrowsTest2.txt"); //文件不存在
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file2));
int len;
while((len = bis.read())!=-1) {
System.out.print((char)len);
}
bis.close();
}
}
throws:写在方法的声明处。指出此方法执行时,可能会抛出的异常类型。一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象。此对象满足throws后异常类型时,就会被抛出。异常代码后面的代码就不会再执行了。(不建议使用在处理io流)
try(){}catch{}finally{}
try{
将可能出现异常的代码在try语句当中进行处理操作
}
catch(Exception e){
当try当中出现异常时,有catch捕获对出现的异常进行处理操作
}
finally{
我们都知道,进行io流操作当中,一定要关闭资源,否则资源未得到释放,则可能会出现资源的流失、
为什么要放在finally比较合适:
因为如果将关闭close()操作放在try当中,异常报错发生在close()操作之前,资源会发生不能释放的情况
finally最终的意思,意味着在catch捕获异常之前,fianlly要先于catch.
}
public static void main(String[] args) {
//创建两个缓冲流
BufferedInputStream bis =null;
BufferedOutputStream bos = null;
File file1 = new File("f:\\bb\\ThrowsTest.txt");
File file2 = new File("f:\\bb\\ThrowsTest2.txt");
/*
* try将{
* 可能出现异常的代码
}
*/
try {
bis = new BufferedInputStream(new FileInputStream(file1));
bos = new BufferedOutputStream(new FileOutputStream(file2));
byte[] buffer = new byte[1024];
while(bis.read(buffer)!=-1) {
bos.write(buffer);
}
System.out.println(new String(buffer));
} catch (IOException e) {
e.getStackTrace();
}
/*
* finally {
* 抛出异常之前一定会执行finally操作
* 该操作需要处理的就是当缓冲流被打开时执行关闭操作。
* }
*/
finally {
try {
if(bis!=null) {
bis.close();
}
if(bos!=null) {
bos.close();
}
} catch (IOException e2) {
e2.getStackTrace();
}
}
}
在JDK7之前对于IO流的异常处理操作使用try{}catch(){}finally{}方法.
在JDK9新的特性当中:
try(){}catch(){}
可以不需要写finally操作,也不需要对流进行close()方法的操作;
try(Resource resource = xxx) //可指定多个资源
{
//work with resource
}
其用法是:try(Resource resource = xxx)数据流xxx会在 try 执行完毕后自动被关闭,
前提是,这些可关闭的资源必须实现 java.lang.AutoCloseable 接口。
try()的括号当中可以指定多个资源以 “;”分号作为一句结束语句。最后一句可不加;
public static void main(String[] args) {
/*
* try(){}
* try(Resource resource = xxx) //可指定多个资源
{
//work with resource
}
其用法是:try(Resource resource = xxx)数据流xxx会在 try 执行完毕后自动被关闭,
前提是,这些可关闭的资源必须实现 java.lang.AutoCloseable 接口。
*/
try(
//System.in标准输入流
InputStreamReader rd = new InputStreamReader(System.in);
//将rd 封装到br当中
BufferedReader br= new BufferedReader(rd);){
String line;
//BufferReader具有readLine方法
//从键盘当中输入:
System.out.print("请输入一行字符串:");
while((line=br.readLine())!=null) {
//判断每一行输入:如果为"exit" 则退出循环
if("exit".equals(line)) {
System.out.println("退出成功!");
System.exit(1);
}
System.out.println(line);
System.out.print("请重新输入一行字符串:");
}
}catch (IOException e) {
e.getStackTrace();
}
}
从代码中不难发现,此方法并没有关闭操作close()方法来释放资源.
因为该方法具有自动释放资源的特性,数据流BufferReader会在 try 执行完毕后自动被关闭,前提是,这些可关闭的资源必须实现 java.lang.AutoCloseable 接口。
通过查询JAVA的API发现一部分数据流继承AutoCloseable接口