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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wf111sxwf 中级黑马   /  2014-11-14 21:45  /  1627 人查看  /  15 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. package cn.itcast.io.test;

  2. import java.io.BufferedWriter;
  3. import java.io.File;
  4. import java.io.FileWriter;
  5. import java.io.FilenameFilter;
  6. import java.io.IOException;
  7. import java.util.ArrayList;
  8. import java.util.List;

  9. /*
  10. * 获取指定目录下指定拓展名的文件(包含子目录中的)
  11. * 将这些文件的绝对路径写入到一个文本文件中。
  12. *
  13. * 简单说就是建立一个指定拓展名的文件的列表。
  14. *
  15. *
  16. * 思路:
  17. * 1.必须进行深度遍历。
  18. * 2.要在遍历的过程中进行过滤,将符合条件的内容存储到容器中。
  19. * 3.对容器中的内容进行遍历,并将绝对路径写入到文件中。
  20. *
  21. */
  22. public class Test {

  23.         public static void main(String[] args) {
  24.                 // TODO Auto-generated method stub
  25.                 File dir = new File("e:\\jav0331");
  26.                 FilenameFilter filter = new FilenameFilter(){
  27.                        
  28.                         @Override
  29.                         public boolean accept(File dir, String name) {
  30.                                 // TODO Auto-generated method stub
  31.                                 return name.endsWith(".java");  //这里函数的参数中传入了一个File对象,而返回值的运算中并没有用到这个对象,那么问题就来了, 参数中传入这个对象是干什么用的?
  32.                         }
  33.                        
  34.                 };
  35.                
  36.                 List<File>list = new ArrayList<File>();
  37.                
  38.                 getFiles(dir,filter,list);
  39.                
  40.                 File destFile = new File(dir,"javalist.txt");
  41.                
  42.                 writeToFile(list,destFile);
  43.        
  44.         }
  45.         /**
  46.          * 对指定目录中的内容进行深度遍历,并按照指定过滤器进行过滤。
  47.          * 将过滤后放入内容存储到List中。
  48.          *
  49.          *
  50.          *
  51.          */
  52.        
  53.         public static void getFiles(File dir,FilenameFilter filter,List<File>list){
  54.                
  55.                 File[]files = dir.listFiles();
  56.                
  57.                 for(File file : files){
  58.                         if(file.isDirectory()){
  59.                                
  60.                                 //递归拉!
  61.                                 getFiles(file,filter,list);
  62.                         }
  63.                         else{
  64.                                
  65.                                 //对遍历到的文件进行过滤器的过滤。将符合条件的File对象存储到List集合中。
  66.                                
  67.                                 if(filter.accept(dir, file.getName())){
  68.                                        
  69.                                         list.add(file);
  70.                                 }
  71.                         }
  72.                 }
  73.                
  74.         }
  75.        
  76.        
  77.         public static void writeToFile(List<File>list,File destFile) {
  78.                
  79.                 BufferedWriter bufw = null;
  80.                
  81.                 try {
  82.                         bufw = new BufferedWriter(new FileWriter(destFile));
  83.                        
  84.                         for(File file : list){
  85.                                 bufw.write(file.getAbsolutePath());
  86.                                 bufw.newLine();
  87.                                 bufw.flush();
  88.                         }
  89.                        
  90.                  } catch (IOException e) {
  91.                                 throw new RuntimeException("写入失败");
  92.                 }finally{
  93.                         if(bufw != null)
  94.                                 try {
  95.                                         bufw.close();
  96.                                 } catch (IOException e) {
  97.                                         throw new RuntimeException("关闭失败") ;
  98.                                 }
  99.                 }
  100.                
  101.        
  102.         }
  103.        
  104. }
复制代码



小弟不才问题已经写到了代码的注释中  望大神解答啊

15 个回复

倒序浏览
File dir, String name
dir表示的是当前的目录,而name是这个当前目录中的文件名称
回复 使用道具 举报
zhangyangLengen 发表于 2014-11-15 09:48
File dir, String name
dir表示的是当前的目录,而name是这个当前目录中的文件名称 ...

嗯 这个我知道。  但是我们在定义函数时, 所有的参数都必须是有用的,也就是运算的时候肯定会用到参数列表中的参数,而 毕老师讲的这个例子里,  过滤器中 的 accpt方法 的返回值是 name.endsWith(".java");    和参数中的File  一点关系都没有,那么我们为什么要在参数中 传入这个File呢?     下面用这个过滤器对文件名进行过滤的时候 , if(filter.accept(dir, file.getName())){//  这里 if的判断条件改成  file.getName().endsWith(".java")  是否可以   如果可以的话 那么 这个过滤器也就没有必要了。  我是在不懂啊

71.                                       

72.                                        list.add(file);
回复 使用道具 举报
因为:这是接口FileNameFilter定义的accept方法,可能有时候会用到
回复 使用道具 举报
找源码看看就明白了 我之前也对accept方法的工作原理感到奇怪 就看了下源码就明白了
回复 使用道具 举报
wf111sxwf 来自手机 中级黑马 2014-11-15 19:42:53
地板
DamonZh 发表于 2014-11-15 17:02
找源码看看就明白了 我之前也对accept方法的工作原理感到奇怪 就看了下源码就明白了 ...

好的多谢提点
回复 使用道具 举报
郑飞 高级黑马 2014-11-15 20:00:26
7#
你可以试着在accept中把dir路径和文件名连接以后 直接添加到事先定义好的容器中 就省去了 后面再回过头来收集这个列表了
回复 使用道具 举报
本帖最后由 cvnmklop 于 2014-11-15 22:32 编辑
wf111sxwf 发表于 2014-11-15 13:03
嗯 这个我知道。  但是我们在定义函数时, 所有的参数都必须是有用的,也就是运算的时候肯定会用到参数列 ...

哥们,你是犯了想当然的错误。accept在设计的时候设计者无从知道后来的使用者会使用哪个文件来判断即设计者不知道具体的文件路径。你不把文件夹传进去,name怎么可能返回你想要的文件夹下的文件名呢?这就好比你不打开抽屉怎么拿抽屉里的东西。这个FilenameFilter接口是用在需要用到的方法上的例如下面两个方法,作为参数传入能简化自己编写代码,一般这种就是直接写匿名内部类了
FileDialog.setFilenameFilter(java.io.FilenameFilter)
File.list(java.io.FilenameFilter)
你现在编的程序完全可以不用这个方法。

回复 使用道具 举报
striker 中级黑马 2014-11-15 22:15:48
9#
比较高端
回复 使用道具 举报
  1. /*
  2. 这是File类中的源码,从listFiles()可以看到,调用了filenamesToFiles方法,该方法将一个字符串数组转换为File数组,在该方法中传入了list()函数的返回值作为参数,并将FileNameFilter类型的参数filter(这个就是你定义的过滤器)传给list()函数。那么list函数的作用是什么呢?
  3. */
  4. public File[] listFiles(FilenameFilter filter) {
  5. return filenamesToFiles(list(filter));
  6.     }
  7. /*
  8. 看下面list()的源码
  9. for循环内,调用了过滤器filter的accept()函数,并将this指针作为参数传进去,这里的this不就是指的File类的子类吗?
  10. 也就是你28行 File dir = new File("e:\\jav0331"); 这里定义的目录,即要进行查找的目录。分析的应该没错吧?
  11. */
  12. public String[] list(FilenameFilter filter) {
  13.         String[] filenames = list();
  14.         if (filter == null || filenames == null) {
  15.             return filenames;
  16.         }
  17.         List<String> result = new ArrayList<String>(filenames.length);
  18.         for (String filename : filenames) {
  19.             if (filter.accept(this, filename)) {
  20.                 result.add(filename);
  21.             }
  22.         }
  23.         return result.toArray(new String[result.size()]);
  24.     }
复制代码




回复 使用道具 举报
wf111sxwf 来自手机 中级黑马 2014-11-16 14:48:31
11#
cvnmklop 发表于 2014-11-15 22:01
哥们,你是犯了想当然的错误。accept在设计的时候设计者无从知道后来的使用者会使用哪个文件来判断即设计 ...

这位仁兄 这代码不是我写的 而是毕老师视频里的代码。下面的算法里不需要用到过滤器 我也是这么想的。我的问题只是针对毕姥爷的这段代码的 并不是说我不懂 list(new FilenameFilter)这个方法的工作原理 我的问题你看我是如何回复2楼的
回复 使用道具 举报
wf111sxwf 来自手机 中级黑马 2014-11-16 14:57:58
12#
好吧我是问题描述的不清楚了,这是毕老师视频里讲的一道习题,我的问题其实是我觉得毕老师这段代码用到过滤器其实是不是鸡肋了,大家看不清楚上面的代码的话可以去毕老师基础视频里去找 视频标题是。IO流文件清单列表
回复 使用道具 举报
wf111sxwf 来自手机 中级黑马 2014-11-16 15:08:53
13#
cvnmklop 发表于 2014-11-15 22:01
哥们,你是犯了想当然的错误。accept在设计的时候设计者无从知道后来的使用者会使用哪个文件来判断即设计 ...

  下面用这个过滤器对文件名进行过滤的时候 , if(filter.accept(dir, file.getName())){//  这里 if的判断条件改成  file.getName().endsWith(".java")  是否可以   如果可以的话 那么 这个过滤器也就没有必要了。   其实我的问题就是这个 可能是我问的不清楚。所以各位论坛前辈不用解释list(new FilenameFilter)了。就针对这个问题求助。感谢各位大神前辈
回复 使用道具 举报
wf111sxwf 来自手机 中级黑马 2014-11-16 15:12:28
14#
DamonZh 发表于 2014-11-15 23:29

感谢前辈回答 其实我的问题不是不懂list 方法中的过滤器的工作原理。具体问题你看楼下吧。感谢前辈的回答
回复 使用道具 举报
本帖最后由 爱学习的小明 于 2014-11-16 17:54 编辑

你是复写了FilenameFilter的一个方法,这个接口里面可能还有其他的方法会用到File dir这个参数,那些方法都是私有的方法,只有这个给你复写的方法对外暴露,让你复写,因为其他私有方法要用到这个参数,所以它让暴露的方法需要传入一个File dir参数进来,以便接口内的其他私有方法能够使用这个参数。这里面用到了反射技术,获取到这个暴露的accept方法,并获取到方法的参数给接口内的其他私有方法用,所以,这个接口对外提供复写的accept方法时,一定要提供File dir这个参数。你学到张孝祥老是的高新技术就会明白了。

点评

你解释的最清楚,楼上的都没说到点子上。FilenameFilter是一个独立的接口,不可能仅仅只是一个accept那么简单  发表于 2015-2-28 23:37
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马