首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >安卓中对于文件夹的综合操作

安卓中对于文件夹的综合操作

作者头像
张风捷特烈
发布于 2018-11-29 10:11:02
发布于 2018-11-29 10:11:02
1.8K00
代码可运行
举报
运行总次数:0
代码可运行
零、前言

手机SD卡里有很多文件夹,感觉挺乱的,写个代码整理一下吧,就当巩固一下文件操作 封装一下文件夹信息,更方便获取其中的信息,如总大小,文件个数、文件夹个数 很多文件隐藏着,让它暴漏出来,获取空文件夹,然后清理一下空文件夹 自定义文件夹大小的过滤,最后以一个文件夹的浏览器的小案例总结全文。

一、获取文件夹信息
1.初阶:获取一个文件夹内容的大小

直接获取文件夹的length()为0,可以通过递归遍历出所有文件夹的文件大小,再累加。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private long dirSize(File dir) {
    //遍历文件夹
    long size = 0;
    for (File file : dir.listFiles()) {
        if (file.isFile()) {
            size += file.length();
        } else {
            dirSize(file);
        }
    }
    return size;
}

查看文件夹大小.png

扫描一下SD卡使用总大小
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
10-26 12:47:34.456 23505-23906/com.toly1994.ti_rp D/SDCardClear: 扫描结束,40935.586M   

2.低阶:封装一下文件夹的信息:DirBean
1).看一下运行结果,大致了解一下这个bean对象
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
DirBean{
    path='/storage/emulated/0/DCIM',
    name='DCIM', 
    dirCount=18, 
    fileCount=2720, 
    length=2.5565107GB,
    modifyTime=2018-10-17 23:16:53
}   
2).DirBean代码实现:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 作者:张风捷特烈<br/>
 * 时间:2018/10/26 0026:13:20<br/>
 * 邮箱:1981462002@qq.com<br/>
 * 说明:文件夹对象
 */
public class DirBean {
    
    private File dir;//文件对象
    private String path; //文件路径
    private String name;//文件夹名
    private int dirCount;//文件夹数量
    private int fileCount;//文件的个数
    private long length; //文件夹大小
    private Long modifyTime;//最后修改时间
    
    public DirBean(File dir) {
        if (dir.isFile()) {
            return;
        }
        this.dir = dir;
        path = dir.getAbsolutePath();
        name = dir.getName();
        modifyTime = dir.lastModified();
    }

    //get、set方法省略...
    //格式化后的文件大小
    public String getLengthFormated() {
        String result = "";
        if (length < 1024) {
            result = length + "B";
        } else if (length < 1024 * 1024) {
            result = length / 1024.f + "KB";
            L.d(length + "----大小:" + length / 1024.f + "KB");
        } else if (length > 1024 * 1024) {
            result = length / 1024.f / 1024 + "MB";
        }
        if (length > 1024 * 1024 * 1024) {
            result = length / 1024.f / 1024 / 1024 + "GB";
        }
        return result;
    }
    //格式化后的时间
    public String getModifyTimeFormated() {
        return new SimpleDateFormat("yyyy-MM-dd kk:mm:ss", Locale.CHINA).format(getModifyTime());
    }

    @Override
    public String toString() {
        return "DirBean{" +
                ", path='" + path + '\'' +
                ", name='" + name + '\'' +
                ", dirCount=" + dirCount +
                ", fileCount=" + fileCount +
                ", length=" + getLengthFormated() +
                ", modifyTime=" + getModifyTimeFormated() +
                '}';
    }
}
3).获取文件夹信息填充对象

通过getSizeLocal递归遍历文件夹,由于size、fileCount、dirCount是成员变量,递归中找不到置零时机 如果不置零,对象不死,每次调用都会叠加,这里用一个方法调用getSizeLocal,之后置零

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private long size = 0;
    private int fileCount = 0;
    private int dirCount = 0;

    public DirBean getSize(File dir) {
        DirBean dirBean = getSizeLocal(dir);
        size = 0;
        fileCount = 0;
        dirCount = 0;
        return dirBean;
    }
    private DirBean getSizeLocal(File dir) {
        DirBean dirBean = new DirBean(dir);
        //遍历文件夹
        for (File file : dir.listFiles()) {
            if (file.isFile()) {
                fileCount++;
                size += file.length();//是文件是长度增加
            } else {
                dirCount++;
                getSizeLocal(file);//不是文件时递归
            }
        }
        dirBean.setLength(size);
        dirBean.setFileCount(fileCount);
        dirBean.setDirCount(dirCount);
        return dirBean;//返回文件夹大小
    }

从手机上来看,名称、时间、大小是没问题,经测试,手机上的未显示隐藏的文,所以数目少一些

查看文件夹信息.png


3.常阶:获取一个文件夹下的所有文件夹的大小
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static long dirListSize(File dir) {
    //将size改成局部变量
    long size = 0;
    for (File file : dir.listFiles()) {
        if (file.isFile()) {
            size += file.length();
        } else {
            size = dirListSize(file);
            if (size < 1024) {//根据文件夹大小决定采用的单位
                L.d(file + "----大小:" + size + "B");
            } else if (size < 1024 * 1024) {
                L.d(file + "----大小:" + size / 1024.f + "KB");
            } else if (size > 1024 * 1024) {
                L.d(file + "----大小:" + size / 1024.f / 1024 + "MB");
            }
        }
    }
    return size;
}

查看文件夹下所有文件夹大小.png

4.高阶:将文件夹的所有文件夹大小信息输出到SD卡中
1).用列表保存数据
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public long dirListSize(File dir, List<String> list) {
    //将size改成局部变量
    long size = 0;
    for (File file : dir.listFiles()) {
        if (file.isFile()) {
            size += file.length();
        } else {
            size = dirListSize(file, list);
            if (size < 1024) {//将信息添加到集合
                list.add(file + "----大小:" + size + "B");
            } else if (size < 1024 * 1024) {
                list.add(file + "----大小:" + size / 1024.f + "KB");
            } else if (size > 1024 * 1024) {
                list.add(file + "----大小:" + size / 1024.f / 1024 + "MB");
            }
        }
    }
    return size;
}
2).将列表中的数据写出到SD卡文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 将文件列表每项的路径保存到目标文件
 *
 * @param list   列表
 * @param target 目标路径
 */
public void writeList2File(List<String> list, String target){
    BufferedWriter bfw = null;
    try {
        bfw = new BufferedWriter(new FileWriter(target));
        for (String s : list) {
            bfw.write(s);
            bfw.newLine();
            bfw.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bfw != null) {
                bfw.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

可见:一共37751个文件夹,每个文件夹大小的路径都保存到文件中了。

将信息保存到文件中.png


二、空文件夹
1.空文件夹的检测比较简单,将加入列表的条件限定一下即可
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 获取某文件夹下的所有空文件夹
 *
 * @param dir  根文件夹
 * @param list 列表
 * @return 大小
 */
public long filterEmptyDir(File dir, List<String> list) {
    //将size改成局部变量
    long size = 0;
    for (File file : dir.listFiles()) {
        if (file.isFile()) {
            size += file.length();
        } else {
            size = filterEmptyDir(file, list);
            if (size == 0) {
                list.add(file.getAbsolutePath());
                L.d(file + L.l());
            }
        }
    }
    return size;
}

一共8262个空文件夹,比我想象的还要多

空文件夹检测.png

2.删除文件夹
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 /**
  * 删除文件夹里的所有文件
  *
  * @param dir
  */
 public void deleteDir(File dir) {
     for (File file : dir.listFiles()) {
         if (file.isDirectory()) {
             deleteDir(file);
         } else {
             String name = file.getName();
             boolean ok = file.delete();
             System.out.println(ok ? "成功删除--" + name : "删除失败--" + name);
         }
     }
     dir.delete();
 }

三、升级版,自定义过滤条件

想必应该用过java的比较器,将比较条件向后推延,让用户自定义条件来更灵活控制 拿到空文件夹,拿到大于1000M的文件夹,拿到大小等于32B的文件夹,操作流基本一直,不同的只有比较条件 因此,写一个比较的接口,将实现推迟到用户使用时:

1.比较接口ICondition
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 作者:张风捷特烈<br/>
 * 时间:2018/10/26 0026:16:14<br/>
 * 邮箱:1981462002@qq.com<br/>
 * 说明:比较接口
 */
public interface ICondition<T> {
    /**
     * 比较方法接口
     * @param param 待比较参数
     * @return 是否比较成功
     */
    boolean condition(T param);
}
2.filterDir通过文件夹大小过滤出需要的文件夹
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 根据条件过滤出符合的文件夹
 *
 * @param dir  根文件夹
 * @param list 列表
 * @param condition 条件
 * @return 大小
 */
public long filterDir(File dir, List<String> list, ICondition<Long> condition) {
    //将size改成局部变量
    long size = 0;
    for (File file : dir.listFiles()) {
        if (file.isFile()) {
            size += file.length();
        } else {
            size = filterDir(file, list, condition);
            //条件的使用
            if (condition.condition(size)) {
                list.add(file.getAbsolutePath());
                L.d(file + L.l());
            }
        }
    }
    return size;
}
3.使用:第三参传自定义的比较条件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
List<String> emptyList = new ArrayList<>();
dirHelper.filterDir(rootFile, emptyList, new ICondition<Long>() {
    @Override
    public boolean condition(Long param) {
        //return param == 0;//过滤出空文件夹
        return param > 1024 * 1024 * 500;//过滤出大小大于500M的文件夹
    }
});
四、显示SD卡文件信息
1.效果如图:点击文件夹则进入文件夹里面,会显示文件夹大小及文件大小。

进入时显示SD卡根目录

点击文件夹显示内部文件

2.辅助函数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 格式化文件大小
 * @param length 文件长度
 * @return 文件大小
 */
public static String formatLong2M(long length) {
    String result = "";
    if (length < 1024) {
        result = length + "B";
    } else if (length < 1024 * 1024) {
        result = length / 1024.f + "KB";
    } else if (length > 1024 * 1024) {
        result = length / 1024.f / 1024 + "MB";
    }
    if (length > 1024 * 1024 * 1024) {
        result = length / 1024.f / 1024 / 1024 + "GB";
    }
    return result;
}
3.操作比较简单,这里用ListView并且已封装。可见:ListView的封装

看图写界面应该不麻烦,布局文件太长,就不贴了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class SDShowActivity extends AppCompatActivity {
    
    @BindView(R.id.id_lv)
    ListView mIdLv;
    private File[] mFiles;
    private MyLVAdapter<File> mMyAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        //显示ListView
        showListView(new File(PathUtils.getSDPath()));
        //点击时更新ListView
        mIdLv.setOnItemClickListener((parent, view, position, id) -> showListView(mFiles[position]));
    }

    private void showListView(File file) {
        mFiles = file.listFiles();
        mMyAdapter = new MyLVAdapter<File>(this, mFiles, R.layout.item_text_only) {
            @Override
            public void setData(MyLVHolder holder, File data, int position) {
                holder.setText(R.id.id_tv_name, data.getName());
                holder.setImageViewRes(R.id.id_iv_pic, data.isDirectory() ? R.mipmap.icon_dir : R.mipmap.icon_file);

                if (data.isDirectory()) {
                    holder.setText(R.id.id_tv_size,
                            StrUtil.formatLong2M(DirHelper.newInstance().getDirBean(data).getLength()));
                } else {
                    holder.setText(R.id.id_tv_size, StrUtil.formatLong2M(file.length()));
                }
            }
        };
        mIdLv.setAdapter(mMyAdapter);
    }

}
4.布局文件:待完善点
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1.非常大的文件加获取大小比较耗时,最好显示文件夹大小时新开线程
2.可以模拟栈来进行返回到上层文件夹的操作,不然就直接退出了
3.可拓展更多的功能点,可以根据文件的后缀名来改变图标

后记:捷文规范
1.本文成长记录及勘误表

项目源码

日期

备注

V0.1--无

2018-10-26

安卓中对于文件夹的综合操作

2.更多关于我

笔名

QQ

微信

爱好

张风捷特烈

1981462002

zdl1994328

语言

我的github

我的简书

我的CSDN

个人网站

3.声明

1----本文由张风捷特烈原创,转载请注明

2----欢迎广大编程爱好者共同交流

3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正

4----看到这里,我在此感谢你的喜欢与支持

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.10.26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
I/O 流总结
当不同的介质之间有数据交互的时候,JAVA就使用流来实现。 数据源可以是文件,还可以是数据库,网络甚至是其他的程序
默 语
2024/11/20
1010
I/O 流总结
杂篇-从整理文件发起的杂谈[-File-]
有些东西很简单,简单到你不想去想,比如:为什么天是蓝的?--局限物语 零、前言 说一下本篇的初衷: coder盘作为工作盘有点乱,想整理一下 也想寻求一个方便管理工程的点子,既然File类玩的滚瓜
张风捷特烈
2019/03/04
5140
杂篇-从整理文件发起的杂谈[-File-]
Java总结IO篇之File类和Properties类
打开颜色选择器 :读流I-->字符串分割-->字符串存入Map-->使用Map对象还原用户配置 修改配置时 :写流O-->创建Map对象-->字符串拼接-->字符串存入配置文件
张风捷特烈
2018/10/12
6240
Java总结IO篇之File类和Properties类
Java文件操作大全
用户1696846
2023/08/25
2630
下载谷歌离线地图瓦片图「建议收藏」
项目中遇到一个需求,需要将某个地图区域的离线地图下载下来,整理很多网上的资料自己实现根据起始点的经纬度下载离线地图,代码如下
全栈程序员站长
2022/11/08
2.8K1
递归就是这么简单
【这是狗哥的第51篇文章】 来自我的好朋友,EvilSay 投稿的文章。我稍微润色了一下,以下是原文: 1、什么是递归?
JavaFish
2019/10/16
4810
mybatis的物理分页:mybatis-paginator
文件分割与合并是一个常见需求,比如:上传大文件时,可以先分割成小块,传到服务器后,再进行合并。很多高大上的分布式文件系统(比如:google的GFS、taobao的TFS)里,也是按block为单位,
菩提树下的杨过
2018/01/19
9460
mybatis的物理分页:mybatis-paginator
【AI帮我写代码,上班摸鱼不是梦】调教ChatGPT过程全记录,让它帮我写程序!
想想看到底哪个文件夹占的空间比较大,好做针对性的删除和清理。奈何Windows系统没有查看文件夹大小的工具,只能鼠标放在某个文件夹上,等提示:
万猫学社
2023/09/01
4670
【AI帮我写代码,上班摸鱼不是梦】调教ChatGPT过程全记录,让它帮我写程序!
系统学习javaweb-03-IO(Input Output)
IO技术主要的作用是解决设备与设备之间的数据传输问题 File类可以描述一个文件或者一个文件夹
csxiaoyao
2019/02/15
1.1K0
15:IO之File、Properties类
第一  File类 一、概述:File类是有文件或文件件封装而来的对象,可以操作其属性信息,这个类的出现弥补了流的不足,流只能操作数据 1、特点: 1)用来将文件或文件夹封装成对象 2)方便于对文件与文件夹的属性信息进行操作 3)File对象可以作为多数传递给流的构造函数 2、File类常见方法: 实例: public class FileDemo {      public static void main(String[] args) {  //      consMethod();  //     
六月的雨
2018/05/14
8890
【Java】File类、递归
java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。
陶然同学
2023/02/27
7470
【Java】File类、递归
File 类与文件操作
1 File类与文件操作就 输入/输出的英文单词是Input/Output, 因此,输入/输出操作通常简称为I/O操作。Java的I/o类和接口主要包含在java.io包中(从JDK 1.4起引入了与缓冲区、通道有关的新I/O类库,它们位于Java.io包中) 。java.io包提供了通过数据流、序列化与反序列化和文件系统实现输人、输出的功能,如果程序中需要导人其中的类、接口,需要附加"import java.io.Xxx!"或"import java.io.*;”语句(Xxx是类或接口名) 由于受各种因
Java学习
2018/04/17
7660
java实现基于关键字的文件夹(文件)的搜索、文件夹(文件)的复制、删除
最近在做一个项目,需要实现这几项功能,上网查了很多资料,自己研究了好几天终于实现了,现在与大家分享一下。 一、JAVA实现文件夹的搜索   在百度搜索N个技术文章,从哪些大牛们共享的资料中终于写出了我想要的代码。成功实现了对文件夹的搜索。   其原理是新定义个FileListener类使其实现ActionListener和Runnable接口。将其绑定在JButton上。在向FileListener的对象传入要搜索的文件夹名称时,会先列出系统所有盘符,并开启多个线程依次搜索各个盘符,其实现原理是先列出各个盘
10JQKA
2018/05/09
2K0
15 Java的文件管理
当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。 f.createNewFile();
acc8226
2022/05/17
3730
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
刘大猫
2024/11/19
820
文件操作与文件夹操作
1.文件操作 package TestFile;/* * zt * 2020/8/6 * 16:47 * 文件操作 1.创建文件 2.删除文件 3.获取信息 4.判断 5.修改名字 */ import java.io.File; import java.io.IOException; import java.sql.Date; public class FileOperate { public s
2020/10/23
1.1K0
java实现csv大文件拆分,每个小文件都有标题行
开发中,我们经常需要导入csv文件到数据库中,但是如果csv文件太大了,可能会报错,这时候可以对csv文件进行拆分,分批导入。本节就以spring boot项目为例实现csv大文件拆分并输出拆分后的zip包。
jiankang666
2022/05/12
1.8K0
java实现csv大文件拆分,每个小文件都有标题行
相关推荐
I/O 流总结
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验