分享
 
 
 

遍历深层次的树状结构 查找硬盘中的 “java.exe”

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

原文:http://www.yi-dao.com/works/model/sample/findFiles.htm

遍历深层次的树状结构。这里的例子是查找所有本地硬盘中的“java.exe”文件。

当向一个深层的目录寻找特定的文件时,很容易想到通过不断地迭代来遍历。

import java.io.File;

public class FileSearchTool {

public static void main(String[] args) {

String toFind = "java.exe";

File[] roots = File.listRoots();

for (int i = 0; i < roots.length; i++) {

searchList(roots[i], toFind);

}

}

public static void searchList(File file, String toFind) {

File[] files = file.listFiles();

if (files != null) {

for (int i = 0; i < files.length; i++) {

if (files[i].isDirectory()) {

searchList(file, toFind);

}

else if (files[i].getName().equals(toFind)) {

System.out.println(files[i].getAbsolutePath());

}

}

}

}

}

上面的代码表面上看好象可以完成任务,可上面的方法却是无效的。上面忽略了目录的深度与广度,在递归的过程中不断地分配资源(File[] files = file.listFiles();),而只有当更深层的递归结束时才能结束当前的工作并释放这些资源,这样极容易导致堆栈溢出和 JVM 停止工作。

为了解决这样的问题,应该尽量避免使用递归。不用递归也不分配大量资源的方法才是有效的方法。

下面是不用递归时查找硬盘中的 "java.exe" 的程序。分析这个过程的状态机请见:http://www.yi-dao.com/works/model/sample/findFiles.ydm 下载这个文档,使用“易道模型”打开,易道模型下载:http://www.sharebank.com.cn/soft/soft_view.php?id=11135

-------------------------------------------------------

public class Test{

public static void main(String[] args) {

File[] roots = File.listRoots();

String nameToFind = "java.exe";

for (int i = 0; i < roots.length; i++) {

File[] files = findFiles(roots[i], nameToFind);

for (int j = 0; j < files.length; j++) {

System.out.println(files[j].getAbsolutePath());

}

}

}

public static File[] findFiles(File dir, String nameToFind) {

Stack curPath = new Stack();

curPath.push(dir);

return findFiles(curPath, nameToFind);

}

public static final int FIND_SUB = 0; // 找子节点

public static final int FIND_SIB = 1; // 找同级节点

public static final int FIND_END = 2; // 结束

public static File[] findFiles(Stack curPath, String nameToFind) {

/** 只检测目录 */

class MyDirFilter

implements FileFilter {

public boolean accept(File pathname) {

return (pathname != null) && pathname.isDirectory();

}

}

/** 只检测文件名相同 */

class MyFileFilter

implements FileFilter {

String toFind;

MyFileFilter(String toFind) {

this.toFind = toFind;

}

public boolean accept(File pathname) {

return (pathname != null) && pathname.isFile()

&& toFind.equalsIgnoreCase(pathname.getName());

}

}

MyFileFilter fileFilter = new MyFileFilter(nameToFind);

MyDirFilter dirFilter = new MyDirFilter();

int state = FIND_SUB; // 开始

LinkedHashSet found = new LinkedHashSet();

while (state != FIND_END) {

File dir = (File) curPath.pop(); // 当前目录

// System.out.println(dir.getAbsolutePath());

if (state == FIND_SUB) { // 查找子节点

File[] subDirs = dir.listFiles(dirFilter);

if (subDirs == null || subDirs.length == 0) { // 没有子节点

curPath.push(dir);

state = FIND_SIB; // 下一次需要找同级节点

}

else {

curPath.push(dir);

curPath.push(subDirs[0]);

state = FIND_SUB;

}

}

else if (state == FIND_SIB) { // 查找同级节点

File[] files = dir.listFiles(fileFilter);

if (files != null) {

for (int i = 0; i < files.length; i++) {

found.add(files[i]);

}

}

if (curPath.isEmpty()) {

state = FIND_END; // 已经没有可以找的了,需要退出查找过程

}

else {

File parentDir = (File) curPath.peek();

File[] sibDirs = parentDir.listFiles(dirFilter);

for (int i = 0; i < sibDirs.length; i++) {

if (dir.equals(sibDirs[i])) { // 找到了当前的位置

if (i + 1 < sibDirs.length) { // 存在下一个同级节点

curPath.push(sibDirs[i + 1]);

state = FIND_SUB; // 需要查找子节点

}

else { // 这就是最后一个同级节点

state = FIND_SIB;

}

break;

}

}

}

}

}

return (File[]) found.toArray(new File[found.size()]);

}

}

上面的方法在整个文件目录的遍历过程中只使用了一个 LinkedHashSet 来记录当前的路径信息,并没有在向更深层次遍历时大量开销过多的资源,所以JVM是可以承受的。这样的方法才有效。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有