热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

rxjava遍历文件夹的巨坑

2019独角兽企业重金招聘Python工程师标准递归遍历文件夹java8之前遍历文件夹用File.list(),而rxjava要想遍历文件夹,那么

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

递归遍历文件夹

java 8之前遍历文件夹用File.list(),而rxjava要想遍历文件夹,那么最简单的做法是递归遍历。

public Observable recursiveDir(final File parent) {if (!parent.isDirectory()) {return Observable.just(parent);}File[] files = null;if ((files = parent.listFiles()) == null || files.length == 0){}return Observable.empty();}return Observable.fromArray(files).flatMap(new Function>() {@Overridepublic Observable apply(File file) throws Exception {return recursiveDir(file);}});
}

递归的写法简单写起来爽,不过跑起来就要哭死你了,StackOverflow!OutOfMemory!。不信试试遍历下手机sdcard下面的tencent目录,不是巨慢就是崩溃!


堆栈遍历文件夹

rxJava递归遍历文件夹除了本身递归在队栈保存恢复上消耗系统资源,还因为rxjava在每一层递归中产生一个Observable,而Observable如果是并发的很可能很快就消耗尽线程池资源。既然递归方式不行,那就改成自己维护堆栈的方式遍历呗,直接看代码吧

/*** Created by droidwolf on 2017/11/14.* https://my.oschina.net/droidwolf* 转载请注明*/
public class FileTreeWalker implements Iterable {private ArrayDeque mDirectories =null;private ArrayDeque mFiles = null;public FileTreeWalker walk(File path) {if (mDirectories != null && !mDirectories.isEmpty()) {mDirectories.clear();}if (mFiles != null && !mFiles.isEmpty()) {mFiles.clear();}walkDir(path);return this;}private void walkDir(File path) {if (path == null || !path.exists() || !path.isDirectory()) {return;}final File[] files = path.listFiles();if (files == null || files.length == 0) {return;}if(mDirectories==null) mDirectories = new ArrayDeque(256);if(mFiles==null) mFiles = new ArrayDeque(512);for (File f : files) {if (f.isDirectory()) {mDirectories.push(f);} else {mFiles.addLast(f);}}}@Overridepublic Iterator iterator() {return mIterator;}private final Iterator mIterator=new Iterator() {@Overridepublic boolean hasNext() {return (mFiles!=null &&!mFiles.isEmpty()) || (mDirectories!=null&& !mDirectories.isEmpty());}@Overridepublic File next() {if (mFiles != null && !mFiles.isEmpty()) {final File f = mFiles.pollFirst();return f;} else if (mDirectories != null && !mDirectories.isEmpty()) {final File dir = mDirectories.pop();walkDir(dir);return dir;}return null;}};
}

rxjava调用FileTreeWalker 

Observable.fromIterable(new FileTreeWalker().walk(path)).subscribeOn(Schedulers.io()).filter(file -> {//。。。return false;}).observeOn(AndroidSchedulers.mainThread()).subscribe(fileNext -> {//。。。});

当然也可以在java8中使用FileTreeWalker

StreamSupport.stream(Spliterators.spliteratorUnknownSize(new FileTreeWalker().walk(new File("C:\\")).iterator(),Spliterator.NONNULL),true )
.forEach(file->{if(file.isDirectory()) {System.out.println(file.getName());}else {System.out.println("\t"+file.getName());}
});

 

总结

递归很多时候写的爽快但遇到瓶颈时优化是个头疼的问题,如果语言自带尾递归优化外挂那还好,没有的话还是得改变原来的思路重来。最后得说一下这个FileTreeWalker实际是不安全的,因为它持有文件夹和文件队列,这使得FileTreeWalker在遍历过程中产生状态的变化,如果在多线程中这是个忌讳。至于怎么改,自己看着办吧!:(


转:https://my.oschina.net/droidwolf/blog/1575021



推荐阅读
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 如何使用 `org.eclipse.rdf4j.query.impl.MapBindingSet.getValue()` 方法及其代码示例详解 ... [详细]
  • 深入解析Java虚拟机的内存分区与管理机制
    Java虚拟机的内存分区与管理机制复杂且精细。其中,某些内存区域在虚拟机启动时即创建并持续存在,而另一些则随用户线程的生命周期动态创建和销毁。例如,每个线程都拥有一个独立的程序计数器,确保线程切换后能够准确恢复到之前的执行位置。这种设计不仅提高了多线程环境下的执行效率,还增强了系统的稳定性和可靠性。 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • 卓盟科技:动态资源加载技术的兼容性优化与升级 | Android 开发者案例分享
    随着游戏内容日益复杂,资源加载过程已不仅仅是简单的进度显示,而是连接玩家与开发者的桥梁。玩家对快速加载的需求越来越高,这意味着开发者需要不断优化和提升动态资源加载技术的兼容性和性能。卓盟科技通过一系列的技术创新,不仅提高了加载速度,还确保了不同设备和系统的兼容性,为用户提供更加流畅的游戏体验。 ... [详细]
  • 本文探讨了在任务完成后将其转换为最终状态时的异常处理机制。通过分析 `TaskCompletionSource` 的使用场景,详细阐述了其在异步编程中的重要作用,并提供了具体的实现方法和注意事项,帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 本文深入解析了Django框架中的MVT(Model-View-Template)设计模式,详细阐述了其工作原理和应用流程。通过分析URL模式、视图、模型和模板等关键组件,读者将全面理解Django应用程序的架构体系,掌握如何高效地构建和管理Web应用。 ... [详细]
  • 本文介绍了如何利用ObjectMapper实现JSON与JavaBean之间的高效转换。ObjectMapper是Jackson库的核心组件,能够便捷地将Java对象序列化为JSON格式,并支持从JSON、XML以及文件等多种数据源反序列化为Java对象。此外,还探讨了在实际应用中如何优化转换性能,以提升系统整体效率。 ... [详细]
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • Android中将独立SO库封装进JAR包并实现SO库的加载与调用
    在Android开发中,将独立的SO库封装进JAR包并实现其加载与调用是一个常见的需求。本文详细介绍了如何将SO库嵌入到JAR包中,并确保在外部应用调用该JAR包时能够正确加载和使用这些SO库。通过这种方式,开发者可以更方便地管理和分发包含原生代码的库文件,提高开发效率和代码复用性。文章还探讨了常见的问题及其解决方案,帮助开发者避免在实际应用中遇到的坑。 ... [详细]
  • 本文深入解析了Java 8并发编程中的`AtomicInteger`类,详细探讨了其源码实现和应用场景。`AtomicInteger`通过硬件级别的原子操作,确保了整型变量在多线程环境下的安全性和高效性,避免了传统加锁方式带来的性能开销。文章不仅剖析了`AtomicInteger`的内部机制,还结合实际案例展示了其在并发编程中的优势和使用技巧。 ... [详细]
  • MySQL数据库安装图文教程
    本文详细介绍了MySQL数据库的安装步骤。首先,用户需要打开已下载的MySQL安装文件,例如 `mysql-5.5.40-win32.msi`,并双击运行。接下来,在安装向导中选择安装类型,通常推荐选择“典型”安装选项,以确保大多数常用功能都能被正确安装。此外,文章还提供了详细的图文说明,帮助用户顺利完成整个安装过程,确保数据库系统能够稳定运行。 ... [详细]
  • 在JavaWeb项目架构中,NFS(网络文件系统)的实现与优化是关键环节。NFS允许不同主机系统通过局域网共享文件和目录,提高资源利用率和数据访问效率。本文详细探讨了NFS在JavaWeb项目中的应用,包括配置、性能优化及常见问题的解决方案,旨在为开发者提供实用的技术参考。 ... [详细]
  • 在Python中,是否可以通过使用Tkinter或ttk库创建一个具有自动换行功能的多行标签,并使其宽度能够随着父容器的变化而动态调整?例如,在调整NotePad窗口宽度时,实现类似记事本的自动换行效果。这种功能在设计需要显示长文本的对话框时非常有用,确保文本内容能够完整且美观地展示。 ... [详细]
author-avatar
壮丁1987_536
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有