`
ww2
  • 浏览: 402095 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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

F# 
阅读更多

      一不小心,顺手写了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”,在这样场合下,就肯定不能用了。

分享到:
评论

相关推荐

    package com.test;package com.test;package com.test;package com.test;

    import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class B { public static void main(String[] args) { File file = new ...

    在线图片编辑 图片可拖动 裁剪区固定中间

    在线图片编辑 图片可拖动 裁剪区固定中间 有预览区 项目中应用

    读取sd卡图片

    import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import android.graphics.Bitmap; import android.graphics.BitmapFactory; public class ImageUtil { /** * 获取网络...

    java中文件操作大全

    7. FileInputStream in=new FileInputStream(src); 8. File file=new File&#40;dest&#41;; 9. if(!file.exists()) 10. file.createNewFile&#40;&#41;; 11. FileOutputStream out=new FileOutputStream(file); ...

    Java:二进制方式读取文件

    import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOperation { public static void...

    计算机网络实验报告 获取MAC socket通信

    new java.io.File("d:\\数据库.zip")); // 转换成网络输出流 java.net.ServerSocket ss = new java.net.ServerSocket(9000); java.net.Socket sk = ss.accept(); //DataOutputStream 处理数据 数据的输出...

    有关java上传和File以及FileInputStream的区别

    NULL 博文链接:https://coffeesweet.iteye.com/blog/812263

    Java计算文件MD5值(支持大文件)

    while ((length = fileInputStream.read(buffer)) != -1) { MD5.update(buffer, 0, length); } return new String(Hex.encodeHex(MD5.digest())); } catch (Exception e) { e.printStackTrace(); ...

    java中实现复制文件和文件夹

    FileInputStream input = new FileInputStream(sourceFile); BufferedInputStream inBuff=new BufferedInputStream(input); // 新建文件输出流并对它进行缓冲 FileOutputStream output = new ...

    Java仿Windows 窗口化复制文件功能.rar

      java.io.File fileIn=new java.io.File&#40;file1&#41;; //用路径名生成源文件   java.io.File fileOut=new java.io.File&#40;file2&#41;; //用路径名生成目标文件   FileInputStream fin=new ...

    关于文件复制的程序java

    fis = new FileInputStream(str); fos = new FileOutputStream(strs); byte[] buf = new byte[1024 * 1024]; int len; while ((len = fis.read(buf)) != -1) { fos.write(buf, 0, len); ...

    android 串口驱动

    import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream...

    Java从文件中读取数字证书.rar

     FileInputStream fin = new FileInputStream("c:/mycert.cer");  //获取一个处理X.509证书的证书工厂  CertificateFactory certFactory = CertificateFactory.getInstance("X.509");  //获取证书  Certificate...

    内存溢出xssfworkbook

    File test = new File&#40;"D:\\test.xlsx"&#41;; try { XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(test)); SXSSFWorkbook workbook = new SXSSFWorkbook(wb); Sheet sheet = workbook.getSheetAt...

    xml2jsonjar包

    import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import ...

    java解析txt

    import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.Reader; /** * @author 码农小江 * H20121012.java * 2012-10-12下午11:40:21 */ public ...

    File_实用案例_实现文件拷贝_FileCopy.java

    from = new FileInputStream(from_file); // Create input stream to = new FileOutputStream(to_file); // Create output stream byte[] buffer = new byte[4096]; // To hold file contents int bytes_read; /...

    FileInputStream.java文档

    文件字节输入流,里面有文件字节输入流的相关要点以及经典案例

    二进制转换图片.rar

    File f = new File("f:\\Vista.png"); FileInputStream fis = new FileInputStream( f ); byte[] bytes = new byte[fis.available()]; fis.read(bytes); fis.close(); // 生成字符串 String imgStr...

    java 读取PDF文件中的内容

    java 读取PDF文件中的内容 java 读取PDF文件中的内容

Global site tag (gtag.js) - Google Analytics