安卓中對於資料夾的綜合操作
零、前言
手機SD卡里有很多資料夾,感覺挺亂的,寫個程式碼整理一下吧,就當鞏固一下檔案操作
封裝一下資料夾資訊,更方便獲取其中的資訊,如總大小,檔案個數、檔案夾個數
很多檔案隱藏著,讓它暴漏出來,獲取空資料夾,然後清理一下空資料夾
自定義資料夾大小的過濾,最後以一個資料夾的瀏覽器的小案例總結全文。
一、獲取資料夾資訊
1.初階:獲取一個資料夾內容的大小
直接獲取資料夾的length()為0,可以通過遞迴遍歷出所有資料夾的檔案大小,再累加。
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卡使用總大小
10-26 12:47:34.456 23505-23906/com.toly1994.ti_rp D/SDCardClear: 掃描結束,共40935.586M
2.低階:封裝一下資料夾的資訊:DirBean
1).看一下執行結果,大致瞭解一下這個bean物件
DirBean{ path='/storage/emulated/0/DCIM', name='DCIM', dirCount=18, fileCount=2720, length=2.5565107GB, modifyTime=2018-10-17 23:16:53 }
2).DirBean程式碼實現:
/** * 作者:張風捷特烈<br/> * 時間:2018/10/26 0026:13:20<br/> * 郵箱:[email protected]<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,之後置零
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.常階:獲取一個資料夾下的所有資料夾的大小
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).用列表儲存資料
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卡檔案
/** * 將檔案列表每項的路徑儲存到目標檔案 * * @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.空資料夾的檢測比較簡單,將加入列表的條件限定一下即可
/** * 獲取某資料夾下的所有空資料夾 * * @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.刪除資料夾
/** * 刪除資料夾裡的所有檔案 * * @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
/** * 作者:張風捷特烈<br/> * 時間:2018/10/26 0026:16:14<br/> * 郵箱:[email protected]<br/> * 說明:比較介面 */ public interface ICondition<T> { /** * 比較方法介面 * @param param 待比較引數 * @return 是否比較成功 */ boolean condition(T param); }
2.filterDir通過資料夾大小過濾出需要的資料夾
/** * 根據條件過濾出符合的資料夾 * * @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.使用:第三參傳自定義的比較條件
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.輔助函式
/** * 格式化檔案大小 * @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的封裝
看圖寫介面應該不麻煩,佈局檔案太長,就不貼了。
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.佈局檔案:待完善點
1.非常大的檔案加獲取大小比較耗時,最好顯示資料夾大小時新開執行緒 2.可以模擬棧來進行返回到上層資料夾的操作,不然就直接退出了 3.可拓展更多的功能點,可以根據檔案的字尾名來改變圖示
後記:捷文規範
1.本文成長記錄及勘誤表
專案原始碼 | 日期 | 備註 |
---|---|---|
V0.1--無 | 2018-10-26 | ofollow,noindex">安卓中對於資料夾的綜合操作 |
2.更多關於我
筆名 | 微信 | 愛好 | |
---|---|---|---|
張風捷特烈 | 1981462002 | zdl1994328 | 語言 |
我的github | 我的簡書 | 我的CSDN | 個人網站 |
3.宣告
1----本文由張風捷特烈原創,轉載請註明
2----歡迎廣大程式設計愛好者共同交流
3----個人能力有限,如有不正之處歡迎大家批評指證,必定虛心改正
4----看到這裡,我在此感謝你的喜歡與支援

icon_wx_200.png