尽量避免诸如x.read(new FileInputStream(sourceFile)); 的写法
2007-08-01 23:06
489 查看
一不小心,顺手写了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 = 1; true; 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”,在这样场合下,就肯定不能用了。
原因是这样的:在开发某一个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 = 1; true; 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”,在这样场合下,就肯定不能用了。
相关文章推荐
- 尽量避免诸如x.read(new FileInputStream(sourceFile)); 的写法
- 尽量避免诸如x.read(new FileInputStream(sourceFile)); 的写法
- 尽量避免诸如x.read(new FileInputStream(sourceFile)); 的写法
- 尽量避免诸如x.read(new FileInputStream(sourceFile)); 的写法
- FileInputStream.read(byte[] b),数组长度大于读取内容字节数长度
- source insight,Error:File read error问题
- java.io.EOFException at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
- inputStreamReader(new FileInputStream(file),"UTF-8")出现乱码的问题
- [Ruby笔记]4. ruby 读写文件 File open read write new
- Read in text file line by line php - newline not being detected
- java file to inputstream以及New Document From InputStream读取和写入文件操作实例代码
- java.io.FileInputStream.read()的返回值类型为什么是int而不是byte
- new FileOutputStream("a.bmp") 报错java.io.FileNotFoundException: /a.bmp (Read-only file system)
- Why is using BufferedInputStream to read a file byte by byte faster than using FileInputStream
- [ERROR] Unable to read and import the source file : 'C:\Users\Administrator\.hudson\jobs\Deeplan\wor
- Java IO 文件读取问题记录(class.getResourceAsStream 和 new FileInputStream)
- 源代码修改-ReadSourceFile
- InputStream中read()与read(byte[] b) 标签: bytestringjavafilenullpath 2012-08-21 20:38 15233人阅读 评论(1) 收藏
- sql server 2000 安装错误:the specified file cannot be opened as read-only .ensure the source file is pre
- Source Insight 3 出现错误:Error:File read error