黑马程序员技术交流社区
标题:
Copy文件实例代码中的关闭流的疑惑。
[打印本页]
作者:
皮卫凯
时间:
2012-9-16 17:36
标题:
Copy文件实例代码中的关闭流的疑惑。
本帖最后由 皮卫凯 于 2012-9-16 23:30 编辑
import java.io.*;
class CopyText
{
public static void main(String[] args) throws IOException
{
copy_2();
}
public static void copy_2() {
FileWriter fw = null;
FileReader fr = null;
try
{ fw = new FileWriter("SystemDemo_copy.txt");
//这里放一起try,为什么关闭流要分开try
fr = new FileReader("SystemDemo.java");
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
if(fr!=null)
try
{
fr.close();
// 为什么这两个关闭流要分别分开try,放一起try不也可以吗。
}
catch (IOException e)
{ }
if(fw!=null)
try
{
fw.close();
}
catch (IOException e)
{ }
}
}
作者:
广驰
时间:
2012-9-16 17:42
如果把close放到第一个try里面,那么如果在close执行前出现了错误,可能就会直接退出,close就无法执行,所以系统资源也就得不到释放,而放在finally里面,因为这个里面的语句是必须执行的所以肯定会执行到close,才能释放系统资源
作者:
武庆东
时间:
2012-9-16 18:00
import java.io.*;
class CopyText
{
public static void main(String[] args) throws IOException
{
copy_2();
}
public static void copy_2() {
FileWriter fw = null;
FileReader fr = null;
try
{ fw = new FileWriter("SystemDemo_copy.txt");
//这里放一起try,为什么关闭流要分开try-------这里放到一块就可以了!
fr = new FileReader("SystemDemo.java");
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
if(fr!=null)
try
{
fr.close();
// 为什么这两个关闭流要分别分开try,放一起try不也可以吗-----可以,但是分开写,目的性更强,见后面改写
}
catch (IOException e)
{
throw new exception("读取文件出错"); //添加
}
if(fw!=null)
try
{
fw.close();
}
catch (IOException e)
{
throw new exception("写入文件出错"); //添
加这两个抛出异常,会不会更好呢,代码更清晰! IOException 是异常的父类,我们还可以配置确定的异常!
}
}
}
作者:
皮卫凯
时间:
2012-9-16 23:29
谢谢答复。
作者:
皮卫凯
时间:
2012-9-17 15:49
谢谢答复。
作者:
吴通
时间:
2012-9-18 07:47
首先为什么关闭流的动作要分开?
因为在我们用到try{}catch(){}处理异常的语句,也就是我们的程序可能导致出现异常的繁发生。
异常一旦发生,执行try{}catch(){}语句,try里面的语句有可能执行不到,就被catch捕获异常,从而处理
加入我们把关闭流的动作放在try语句中,这中情况下流就没有关闭。所以关闭流的动作要放在finally语句中,
因为我们知道finally中存放的是一定能执行到的语句,所以不管有没有发生异常,关闭流总能执行
虽然有一种情况下,就是try或者catch中执行到System.exit(0)时,finally中语句执行不到,但是这种情况下
java虚拟机就退出,所以流会自动随之关闭的
为什么要分开try?
分开try是因为他们满足的条件不一样,要限定FileWriteru和FileReader不为空才能关闭。所以我把楼主finally中语句做了修改
finally
{
if(fr!=null)
try
{
if(fr!=null)
fr.close();
// 为什么这两个关闭流要分别分开try,放一起try不也可以吗。
}
catch (IOException e)
{ }
if(fw!=null)
try
{
if(fw!=null)
fw.close();
}
catch (IOException e)
{ }
}
这两个判断语句是关闭的前提,一定要加上!
作者:
梁志冰
时间:
2012-9-18 11:09
吴通 发表于 2012-9-18 07:47
首先为什么关闭流的动作要分开?
因为在我们用到try{}catch(){}处理异常的语句,也就是我们的程序可能导 ...
finally
{
if(fr!=null)
//这里已经做了判断
try
{
if(fr!=null)
//无需再做判断
fr.close();
// 为什么这两个关闭流要分别分开try,放一起try不也可以吗。
}
catch (IOException e)
{ }
if(fw!=null)
//这里已经做了判断
try
{
if(fw!=null)
//无需再做判断
fw.close();
}
catch (IOException e)
{ }
}
楼上说的,我认为无需再做一次判断了,这样有点多余,只要程序稍微改动一下,就很明了:
finally
{
if(fr!=null)
{ //将代码块都使用{}放在if语句下
try
{
fr.close();
// 为什么这两个关闭流要分别分开try,放一起try不也可以吗。
}
catch (IOException e)
{ }
}
if(fw!=null)
{
try
{
fw.close();
}
catch (IOException e)
{ }
}
}
当然了,这样分开两个try也还是有可能会发生问题,就是在第一个 catch (IOException e){ }中,不能直接抛出RuntimeException异常,这样一但第一个try出现异常,那么第二个try是无法执行到的,也就是无法关闭fw.close();
这里有两个解决方案
(1)catch (IOException e){ }不抛运行异常RuntimeException,不让程序停止,这样可以执行到fw.close();
(2)将程序稍作改动:
finally
{
if(fr!=null)
{ //将代码块都使用{}放在if语句下
try
{
fr.close();
// 为什么这两个关闭流要分别分开try,放一起try不也可以吗。
}
catch (IOException e)
{ }
finally {
if(fw!=null)
{
try
{
fw.close();
}
catch (IOException e)
{ }
}
}
}
}
作者:
吴通
时间:
2012-9-18 15:52
我没有看清楚,确实弄错了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2