胡长城(银狐999)BLOG

专注SOA,MDA,EAI,BPM,工作流,J2EE;个人主页http://www.javafox.org

胡长城ID:james999
552409次访问,排名71好友0人,关注者51
J2EE,Workflow,BPM,EAI,SOA,工作流
james999的文章
原创 186 篇
翻译 0 篇
转载 2 篇
评论 623 篇
银狐999的公告
个人主要工作流文档可从 javafox live网络硬盘下载

最近评论
cai123mei456:你认识胡长柱么 ?
cai123mei456:你认识胡长柱么 ?
james999:to shendl: 在普元。
james999:to shendl: 在普元。
shendl:胡兄现在在国内公司吗? 什么公司,什么Workflow产品吗?
文章分类
收藏
    相册
    50 Relational Blogs
    Hongsoft博客
    J2EE与ERP禅话
    Peter's Blog
    俠盜躶奔漢
    切尔斯基(RSS)
    动物园的猪
    胡奇
    赵斌BLog
    阿飞外传
    55 Workflow Preacher
    Ekkart Kindler
    Michael zur Muehlen
    Wil van der Aalst
    存档
    订阅我的博客
    XML聚合  FeedSky

    原创 尽量避免诸如x.read(new FileInputStream(sourceFile)); 的写法收藏

    新一篇: 俺可爱的小马,差点被淹了 | 旧一篇: Log4j被OSGI撞了一下腰

          一不小心,顺手写了x.read(new FileInputStream(sourceFile)); 这样的代码,却引得自己花费了半个多小时去调试问题。
         原因是这样的:在开发某一个feature的时候,需要对操作的文件进行backup,于是写了诸如下面的代码(以下仅是演示代码,与实际要简易,仅供参考):

    /*
     * XXX是一个处理类,soureFile是一个输入的File object
     
    */

    XXX x 
    = new XXX();
    x.read(
    new FileInputStream(sourceFile));
    ..... 
    //complex logic process

    String sourceFilePath 
    = sourceFile.getPath();
    int maxBackups = 3;

    List
    <File> files = new ArrayList<File>();
    files.add(traFile);
    String base 
    = sourceFile.getPath() + '.';
    for (int generations = 1true; generations++) {
        File f 
    = new File(base + generations);
        files.add(f);
        
    if (!f.exists()) {
            
    break;
        }
    }

    int generations = files.size();
    for (int generation = generations - 1; generation > 0; generation--) {
        
    if (generation > maxBackups) {
            files.get(generation).delete();
        } 
    else {
            
    if(files.get(generation).exists()) files.get(generation).delete();
            files.get(generation 
    - 1).renameTo(files.get(generation));
        }
    }

    ..... 
    //complex logic process
    x.write(new FileOutputStream(sourceFilePath));

    当写完以后,运行TestCase并不是每次都成功,有时候就可以正确生成backup文件,而有时候则没有生成(没有生成的概率大很多)。跟踪了一下,发现当没有正确生成backup的时候,是那段file renameTo没有执行成功。就是如上面代码中“粗粉红色的标记的”:files.get(generation - 1).renameTo(files.get(generation))

    然后进行Debug状态的step by step运行,却每次都成功了。
    仔细了想了想,可能的原因是 files.get(generation - 1) 这个所引对象的对象,在执行renameTo操作的时候,可能还在被某个资源锁定,而没有释放。

    带着个这个想法,把代码从头再过了一遍,终于发现是 x.read(new FileInputStream(sourceFile)); 这段出了问题。因为XXX这个类,在内部处理过程中,并没有对输入的inputstream进行关闭(当然,这是一个正确的设计和实现,一般我们在开发过程中,都不会在“使用者”内部关闭外部的流,这样危险性非常大)。

    但是,为了代码了简洁,很随意的就进行了 x.read(new FileInputStream(sourceFile));  这样的书写

    正是这样的书写,让后面针对soureFile的操作不能执行成功。因为所用在这个soureFile上的InputStream流并没有被“真正关闭”。

    于是改成:
    InputStream is = new FileInputStream(sourceFile);
    x.read(is);
    is.close;
    就可以了。

    当然,并不是说诸如 x.read(new FileInputStream(sourceFile));  的写法不能用,而是尽量避免在“在同一个方法开闭区间内多次引用sourceFile”,在这样场合下,就肯定不能用了。

    发表于 @ 2007年08月01日 23:06:00|评论(loading...)|编辑

    新一篇: 俺可爱的小马,差点被淹了 | 旧一篇: Log4j被OSGI撞了一下腰

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 银狐999