1339932cde82a4360ac9ffb02a840cba442cccb7.svn-base 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package UIB.COM;
  2. import java.io.File;
  3. import java.net.URLDecoder;
  4. import java.util.ArrayList;
  5. import java.util.LinkedList;
  6. import java.util.List;
  7. import java.util.Queue;
  8. /**
  9. * @desc 实现一个支持通配符的基于广度优先算法的文件查找器
  10. * @author 梅贵平{meiguiping}
  11. * @date 2010-8-26
  12. */
  13. public class FileFinder
  14. {
  15. /**
  16. * 查找文件。
  17. *
  18. * @param baseDirName
  19. * 待查找的目录
  20. * @param targetFileName
  21. * 目标文件名,支持通配符形式
  22. * @param count
  23. * 期望结果数目,如果畏0,则表示查找全部。
  24. * @return 满足查询条件的文件名列表
  25. */
  26. public static List findFiles(String baseDirName, String targetFileName,
  27. int count) throws Exception
  28. {
  29. /**
  30. * 算法简述: 从某个给定的需查找的文件夹出发,搜索该文件夹的所有子文件夹及文件,
  31. * 若为文件,则进行匹配,匹配成功则加入结果集,若为子文件夹,则进队列。 队列不空,重复上述操作,队列为空,程序结束,返回结果。
  32. */
  33. List fileList = new ArrayList();
  34. // 判断目录是否存在
  35. // File baseDir = new File(baseDirName);
  36. File baseDir = new File(URLDecoder.decode(baseDirName, "utf-8"));
  37. if (!baseDir.exists() || !baseDir.isDirectory())
  38. {
  39. System.out.println("文件查找失败:" + baseDirName + "不是一个目录!");
  40. return fileList;
  41. }
  42. String tempName = null;
  43. // 创建一个队列,Queue在第四章有定义
  44. Queue queue = new LinkedList();
  45. queue.offer(baseDir);// 入队
  46. File tempFile = null;
  47. while (!queue.isEmpty())
  48. {
  49. // 从队列中取目录
  50. tempFile = (File) queue.poll();
  51. if (tempFile.exists() && tempFile.isDirectory())
  52. {
  53. File[] files = tempFile.listFiles();
  54. for (int i = 0; i < files.length; i++)
  55. {
  56. // 如果是目录则放进队列
  57. if (files[i].isDirectory())
  58. {
  59. queue.add(files[i]);
  60. } else
  61. {
  62. // 如果是文件则根据文件名与目标文件名进行匹配
  63. tempName = files[i].getName();
  64. if (FileFinder.wildcardMatch(targetFileName, tempName))
  65. {
  66. // 匹配成功,将文件名添加到结果集
  67. fileList.add(files[i].getAbsoluteFile());
  68. // 如果已经达到指定的数目,则退出循环
  69. if ((count != 0) && (fileList.size() >= count))
  70. {
  71. return fileList;
  72. }
  73. }
  74. }
  75. }
  76. }
  77. }
  78. return fileList;
  79. }
  80. /**
  81. * 通配符匹配
  82. *
  83. * @param pattern
  84. * 通配符模式
  85. * @param str
  86. * 待匹配的字符串
  87. * @return 匹配成功则返回true,否则返回false
  88. */
  89. private static boolean wildcardMatch(String pattern, String str)
  90. {
  91. int patternLength = pattern.length();
  92. int strLength = str.length();
  93. int strIndex = 0;
  94. char ch;
  95. for (int patternIndex = 0; patternIndex < patternLength; patternIndex++)
  96. {
  97. ch = pattern.charAt(patternIndex);
  98. if (ch == '*')
  99. {
  100. // 通配符星号*表示可以匹配任意多个字符
  101. while (strIndex < strLength)
  102. {
  103. if (wildcardMatch(pattern.substring(patternIndex + 1), str
  104. .substring(strIndex)))
  105. {
  106. return true;
  107. }
  108. strIndex++;
  109. }
  110. } else if (ch == '?')
  111. {
  112. // 通配符问号?表示匹配任意一个字符
  113. strIndex++;
  114. if (strIndex > strLength)
  115. {
  116. // 表示str中已经没有字符匹配?了。
  117. return false;
  118. }
  119. } else
  120. {
  121. if ((strIndex >= strLength) || (ch != str.charAt(strIndex)))
  122. {
  123. return false;
  124. }
  125. strIndex++;
  126. }
  127. }
  128. return (strIndex == strLength);
  129. }
  130. }