`
ww2
  • 浏览: 418124 次
  • 性别: 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 ...

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

    本文将详细探讨“Java上传和File以及FileInputStream的区别”,以及与之相关的知识点。 首先,`File`类在Java中代表一个文件或目录。它提供了许多方法来操作文件,如创建、删除、重命名等。`File`对象不直接包含...

    读取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精典编程100例 31

    import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class FileInputStreamExample { public static void main(String[] args) { try { File file = new File("example....

    读取xls和xlsxjar包

    FileInputStream fis = new FileInputStream("path_to_your_file.xls"); Workbook workbook = WorkbookFactory.create(fis); Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表 // 然后可以遍历行和列,...

    【IT十八掌徐培成】Java基础第13天-04.字节流-FileInputStream-FileOutputStream.zip

    try (FileInputStream in = new FileInputStream(source); FileOutputStream out = new FileOutputStream(dest)) { byte[] buffer = new byte[1024]; int length; while ((length = in.read(buffer)) &gt; 0) { ...

    demo-readexcel.zip

    import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class ReadExcelWithPOI { public static void main(String[] args) throws IOException { FileInputStream fis = ...

    计算机网络实验报告 获取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解析获取Excel中的数据--同时兼容2003及2007

    import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class ExcelReader { public static void main(String[] args) { try (FileInputStream fis = new FileInputStream...

    FileReadWrite with text aread output.zip_In Writing_file readers

    首先,Java提供了一些内置的类来处理文件I/O操作,如`java.io.File`、`java.io.FileInputStream`、`java.io.FileOutputStream`、`java.io.FileReader`、`java.io.FileWriter`以及`java.io.BufferedReader`和`java.io...

    基于ant.jar的文件压缩工具类

    import org.apache.tools.ant.types.FileSet; import org.apache.tools.zip.ZipOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io....

    java代码笔记2010-06-11:java_x_文件_字节流,创建一个一个文件目录,在该目录下创建一个文件 txt, 然后写入内容进去, 再读取文件.

    首先,创建文件目录可以使用`java.io.File`类。这个类提供了许多方法来操作文件和目录。例如,我们可以调用`mkdir()`或`mkdirs()`方法来创建一个新目录。`mkdir()`用于创建单级目录,而`mkdirs()`则可以创建多级目录...

    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...

    commons-compress-1.18-bin.zip

    IOUtils.copy(new FileInputStream(sourceFile), tas); tas.closeArchiveEntry(); } catch (IOException e) { e.printStackTrace(); } ``` 总的来说,Apache Commons Compress库通过`TarArchiveInputStream`、`...

    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读写文件避免中文乱码.pdf

    InputStreamReader read = new InputStreamReader(new FileInputStream(f), "UTF-8"); BufferedReader reader = new BufferedReader(read); String line; while ((line = reader.readLine()) != null) { ...

    使用Java操纵Excel表.doc

    import java.io.File; import java.io.FileInputStream; import jxl.Workbook; File sourcefile = new File("path_to_your_file.xls"); try { FileInputStream fis = new FileInputStream(sourcefile); Workbook ...

    格式化xml字符串,并生成xml文件

    import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import javax.xml.transform.OutputKeys; import javax.xml.transform.Source; import javax.xml.transform.Transformer;...

    带进度条的压缩/解压缩

    try (FileInputStream fis = new FileInputStream(sourceFile); CompressorInputStream cis = new CompressorStreamFactory().createCompressorInputStream(fis)) { File outputFile = new File(destDir, source...

Global site tag (gtag.js) - Google Analytics