A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 第一印象 于 2013-8-25 14:39 编辑

看了老毕的基础教程后,想对文件合并分割器的代码进行一些改进,想增加一个文件切割后删除源文件、文件合并后,删除原来的所有碎片文件的功能,切割后,删除源文件没什么问题,但是,合并后,删除原来的碎片文件,properties文件总是删不掉,并且,如果切割的文件过大,比如我用1.25G的文件测试,在合并时,碎片文件也会有一部分删不掉的,我的内存是3G的(win7-32位的只能识别到这了),在合并时,文件似乎一次性全部加载到了内存,在删除时,内存到了2.6G就出问题了,部分碎片文件删不掉,properties文件是每次都删不掉,这事什么情况,请教!
我把代码贴上来,以下是我的代码,我换上老毕的代码测试合并后删除原来的碎片文件,properties文件也删不掉,不知为何,流已经关闭了,没有打开properties文件,也没有与之相关的程序,就是说该文件在我看来没被引用到,怎么就删不掉了:

--文件合并类

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.SequenceInputStream;
  7. import java.util.ArrayList;
  8. import java.util.Collections;
  9. import java.util.Enumeration;
  10. import java.util.List;
  11. import java.util.Properties;

  12. public class MergeFile {

  13.         //定义配置文件后缀名
  14.         private static final String PROPERTIES_SUFFIX = ".properties";
  15.         //定义碎片文件后缀名
  16.         private static final String PART_SUFFIX = ".part";
  17.         //取缓冲区:1M
  18.         private static final int BUFFERED_SIZE = 1048576;
  19.         
  20.         /**
  21.          * 根据文件路径读取properties配置文件,并合并指定路径下的文件
  22.          * @param filepath 要合并的的碎片文件的目录
  23.          * @param fileMerged 碎片文件合并后文件的存放目录
  24.          * @throws IOException
  25.          * */
  26.         public static void fileMerge(File filepath, File fileMerged) throws IOException {
  27.                 //检测碎片文件目录是否正确
  28.                 if(filepath==null || !filepath.isDirectory()){
  29.                         throw new RuntimeException("提供的碎片文件目录不是一个目录!");
  30.                 }
  31.                
  32.                 //检测碎片文件合并后的存放目录是否正确
  33.                 if(!fileMerged.isDirectory()){
  34.                         boolean flag = fileMerged.mkdirs();
  35.                         if(!flag)
  36.                                 throw new RuntimeException("创建文件存放路径失败,请提供正确的文件存放路径!");
  37.                 }
  38.                
  39.                 //获取properties配置文件
  40.                 File[] propFiles = getFilesBySuffix(filepath, PROPERTIES_SUFFIX);
  41.                 if(propFiles.length != 1){
  42.                         throw new RuntimeException(filepath.getPath()+"下,后缀为.properties的文件不存在或数量不唯一");
  43.                 }
  44.                 Properties prop = getPropObject(propFiles[0]);
  45.                 //从配置文件中读取碎片文件数量
  46.                 String count = prop.getProperty("count");
  47.                 String fileName = prop.getProperty("filename");
  48.                 if(count==null){
  49.                         throw new RuntimeException("配置文件中的信息有误:count属性对应的值为空");
  50.                 }
  51.                
  52.                 //获取被分割的文件碎片
  53.                 File[] partFiles = getFilesBySuffix(filepath,PART_SUFFIX);
  54.                
  55.                 List<FileInputStream> flist = new ArrayList<FileInputStream>();
  56.                 if(Integer.parseInt(count) != partFiles.length)
  57.                         throw new RuntimeException("配置文件中的count属性的值与实际part文件数量不相符");
  58.                
  59.                 //将文件碎片添加到一个集合中
  60.                 for(File f : partFiles){
  61.                         flist.add(new FileInputStream(f));
  62.                 }
  63.                
  64.                 //将文件集合转化为序列流
  65.                 SequenceInputStream sis = fileList2SeqInputStream(flist);
  66.                
  67.                 //合并文件
  68.                 write2Disk(sis, fileMerged, fileName);
  69.                
  70.                 //关闭序列流
  71.                 sis.close();
  72.                
  73.                 //清除碎片文件
  74.                 clearDebrisFiles(filepath);
  75.         }
  76.         
  77.         //清除碎片文件
  78.         private static void clearDebrisFiles(File filepath) {
  79.                 File[] file = filepath.listFiles();
  80.                 for(File f : file){
  81.                         boolean flag = f.delete();
  82.                         if(!flag)
  83.                                 throw new RuntimeException(filepath.getPath()+"下,"+f.getName()+"删除失败!");
  84.                 }
  85.         }

  86.         //将文件集合转化为序列流
  87.         private static SequenceInputStream fileList2SeqInputStream(
  88.                         List<FileInputStream> flist) {
  89.                 Enumeration<FileInputStream> enumList = Collections.enumeration(flist);
  90.                 SequenceInputStream sis = new SequenceInputStream(enumList);
  91.                 return sis;
  92.         }
  93.         
  94.         //根据文件后缀获取文件
  95.         private static File[] getFilesBySuffix(File filepath, String suffix) {
  96.                 File[] propFiles = filepath.listFiles(new FilterBySuffix(suffix));
  97.                 return propFiles;
  98.         }
  99.         
  100.         //获取碎片文件数量
  101.         private static Properties getPropObject(File propFiles) throws IOException,
  102.                         FileNotFoundException {
  103.                 //获取properties配置文件中的信息
  104.                 Properties prop = new Properties();
  105.                 prop.load(new FileInputStream(propFiles));
  106.                 return prop;
  107.         }
  108.         
  109.         //合并文件
  110.         private static void write2Disk(SequenceInputStream sis, File fileMerged, String filename) throws IOException {
  111.                 FileOutputStream out = new FileOutputStream(new File(fileMerged, filename));
  112.                 byte[] buf = new byte[BUFFERED_SIZE];
  113.                 int len = 0;
  114.                 while((len=sis.read(buf))!=-1){
  115.                         out.write(buf, 0, len);
  116.                 }
  117.                 out.close();
  118.         }
  119.         
  120. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
夜默 + 1

查看全部评分

2 个回复

倒序浏览
你都代码量太多了,不好看懂啊,再说了注释太少了!
properties文件删不掉一定是有另一个对象在引用着它,具体是什么我也看不出!有两个解决办法:
1,是找出引用对象,并释放掉.
2,是强制进行垃圾回收,System.gc()  不过这个方法不一定有效,因为垃圾回收机制是独立的线程,系统不一定立即执行.

评分

参与人数 2技术分 +1 黑马币 +10 收起 理由
夜默 + 1
第一印象 + 10 赞一个!

查看全部评分

回复 使用道具 举报 1 0
谢谢,找到地方了,原来从properties文件中获取碎片文件数量的方法是这样的:
  1. //获取碎片文件数量
  2.         private static Properties getPropObject(File propFiles) throws IOException,
  3.                         FileNotFoundException {
  4.                 //获取properties配置文件中的信息
  5.                 Properties prop = new Properties();
  6.                 prop.load(new FileInputStream(propFiles));
  7.                 return prop;
  8.         }
复制代码
在这个方法里,new FileInputStream(propFiles)在操作完毕后没有关闭读取数据的流,所以删不掉properties文件,改成如下代码就行了
  1. //获取碎片文件数量
  2.         private static Properties getPropObject(File propFiles) throws IOException,
  3.                         FileNotFoundException {
  4.                 FileInputStream fis = new FileInputStream(propFiles);
  5.                 //获取properties配置文件中的信息
  6.                 Properties prop = new Properties();
  7.                 prop.load(fis);
  8.                 fis.close();
  9.                 return prop;
  10.         }
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马