黑马程序员技术交流社区
标题:
合并文件后删除原来的properties文件出错
[打印本页]
作者:
第一印象
时间:
2013-8-24 18:36
标题:
合并文件后删除原来的properties文件出错
本帖最后由 第一印象 于 2013-8-25 14:39 编辑
看了老毕的基础教程后,想对文件合并分割器的代码进行一些改进,想增加一个文件切割后删除源文件、文件合并后,删除原来的所有碎片文件的功能,切割后,删除源文件没什么问题,但是,合并后,删除原来的碎片文件,properties文件总是删不掉,并且,如果切割的文件过大,比如我用1.25G的文件测试,在合并时,碎片文件也会有一部分删不掉的,我的内存是3G的(win7-32位的只能识别到这了),在合并时,文件似乎一次性全部加载到了内存,在删除时,内存到了2.6G就出问题了,部分碎片文件删不掉,properties文件是每次都删不掉,这事什么情况,请教!
我把代码贴上来,以下是我的代码,我换上老毕的代码测试合并后删除原来的碎片文件,properties文件也删不掉,不知为何,流已经关闭了,没有打开properties文件,也没有与之相关的程序,就是说该文件在我看来没被引用到,怎么就删不掉了:
--文件合并类
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
public class MergeFile {
//定义配置文件后缀名
private static final String PROPERTIES_SUFFIX = ".properties";
//定义碎片文件后缀名
private static final String PART_SUFFIX = ".part";
//取缓冲区:1M
private static final int BUFFERED_SIZE = 1048576;
/**
* 根据文件路径读取properties配置文件,并合并指定路径下的文件
* @param filepath 要合并的的碎片文件的目录
* @param fileMerged 碎片文件合并后文件的存放目录
* @throws IOException
* */
public static void fileMerge(File filepath, File fileMerged) throws IOException {
//检测碎片文件目录是否正确
if(filepath==null || !filepath.isDirectory()){
throw new RuntimeException("提供的碎片文件目录不是一个目录!");
}
//检测碎片文件合并后的存放目录是否正确
if(!fileMerged.isDirectory()){
boolean flag = fileMerged.mkdirs();
if(!flag)
throw new RuntimeException("创建文件存放路径失败,请提供正确的文件存放路径!");
}
//获取properties配置文件
File[] propFiles = getFilesBySuffix(filepath, PROPERTIES_SUFFIX);
if(propFiles.length != 1){
throw new RuntimeException(filepath.getPath()+"下,后缀为.properties的文件不存在或数量不唯一");
}
Properties prop = getPropObject(propFiles[0]);
//从配置文件中读取碎片文件数量
String count = prop.getProperty("count");
String fileName = prop.getProperty("filename");
if(count==null){
throw new RuntimeException("配置文件中的信息有误:count属性对应的值为空");
}
//获取被分割的文件碎片
File[] partFiles = getFilesBySuffix(filepath,PART_SUFFIX);
List<FileInputStream> flist = new ArrayList<FileInputStream>();
if(Integer.parseInt(count) != partFiles.length)
throw new RuntimeException("配置文件中的count属性的值与实际part文件数量不相符");
//将文件碎片添加到一个集合中
for(File f : partFiles){
flist.add(new FileInputStream(f));
}
//将文件集合转化为序列流
SequenceInputStream sis = fileList2SeqInputStream(flist);
//合并文件
write2Disk(sis, fileMerged, fileName);
//关闭序列流
sis.close();
//清除碎片文件
clearDebrisFiles(filepath);
}
//清除碎片文件
private static void clearDebrisFiles(File filepath) {
File[] file = filepath.listFiles();
for(File f : file){
boolean flag = f.delete();
if(!flag)
throw new RuntimeException(filepath.getPath()+"下,"+f.getName()+"删除失败!");
}
}
//将文件集合转化为序列流
private static SequenceInputStream fileList2SeqInputStream(
List<FileInputStream> flist) {
Enumeration<FileInputStream> enumList = Collections.enumeration(flist);
SequenceInputStream sis = new SequenceInputStream(enumList);
return sis;
}
//根据文件后缀获取文件
private static File[] getFilesBySuffix(File filepath, String suffix) {
File[] propFiles = filepath.listFiles(new FilterBySuffix(suffix));
return propFiles;
}
//获取碎片文件数量
private static Properties getPropObject(File propFiles) throws IOException,
FileNotFoundException {
//获取properties配置文件中的信息
Properties prop = new Properties();
prop.load(new FileInputStream(propFiles));
return prop;
}
//合并文件
private static void write2Disk(SequenceInputStream sis, File fileMerged, String filename) throws IOException {
FileOutputStream out = new FileOutputStream(new File(fileMerged, filename));
byte[] buf = new byte[BUFFERED_SIZE];
int len = 0;
while((len=sis.read(buf))!=-1){
out.write(buf, 0, len);
}
out.close();
}
}
复制代码
作者:
straw
时间:
2013-8-25 04:11
你都代码量太多了,不好看懂啊,再说了注释太少了!
properties文件删不掉一定是有另一个对象在引用着它,具体是什么我也看不出!有两个解决办法:
1,是找出引用对象,并释放掉.
2,是强制进行垃圾回收,System.gc() 不过这个方法不一定有效,因为垃圾回收机制是独立的线程,系统不一定立即执行.
作者:
第一印象
时间:
2013-8-25 13:42
谢谢,找到地方了,原来从properties文件中获取碎片文件数量的方法是这样的:
//获取碎片文件数量
private static Properties getPropObject(File propFiles) throws IOException,
FileNotFoundException {
//获取properties配置文件中的信息
Properties prop = new Properties();
prop.load(new FileInputStream(propFiles));
return prop;
}
复制代码
在这个方法里,new FileInputStream(propFiles)在操作完毕后没有关闭读取数据的流,所以删不掉properties文件,改成如下代码就行了
//获取碎片文件数量
private static Properties getPropObject(File propFiles) throws IOException,
FileNotFoundException {
FileInputStream fis = new FileInputStream(propFiles);
//获取properties配置文件中的信息
Properties prop = new Properties();
prop.load(fis);
fis.close();
return prop;
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2