文件操作是非常通用的,注释都写在源代码中了,不多说~
需要特别说明的是,任务的异步执行和IOperationProgressListener。
拷贝和删除等操作,是比较费时的,采用了异步执行的方式~

Android异步执行,我也是初次了解,在CSDN上找了一篇文章,后续写个单独的例子,单独写1篇介绍。
http://blog.csdn.net/xufenghappy6/article/details/7343899
异步执行+事件通知 是一种比较流行的模式,比同步等待很多时候要好。

另外,特别需要说明的是,Java应用程序中、Android、Windows开发、Linux Shell都会有文件File的概念,他们本质是一样的。
文件的核心概念基本一致,都是用的操作系统的文件概念,不同操作系统之间的区别也不大。
创建、删除、重命名、复制、粘贴,输入-执行-输出,也都一样。

package net.micode.fileexplorer.util;import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;import net.micode.fileexplorer.model.FileInfo;
import android.os.AsyncTask;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
/**文件操作工具类,执行文件的创建、移动、粘贴、重命名、删除等*/
public class FileOperationHelper {private static final String LOG_TAG = "FileOperation";//内部文件集合,用来临时保存复制、移动等操作,用户选择的文件集合private ArrayList<FileInfo> mCurFileNameList = new ArrayList<FileInfo>();private boolean mMoving;private IOperationProgressListener mOperationListener;private FilenameFilter mFilter;public interface IOperationProgressListener {void onFinish();void onFileChanged(String path);}public FileOperationHelper(IOperationProgressListener l) {mOperationListener = l;}public void setFilenameFilter(FilenameFilter f) {mFilter = f;}//根据路径和文件名,创建文件public boolean CreateFolder(String path, String name) {Log.v(LOG_TAG, "CreateFolder >>> " + path + "," + name);File f = new File(Util.makePath(path, name));if (f.exists())return false;return f.mkdir();}//拷贝若干个文件,把文件集合拷贝到“当前文件集合中mCurFileNameList”,可以供“粘贴操作”使用public void Copy(ArrayList<FileInfo> files) {copyFileList(files);}//粘贴,把当前文件集合中“mCurFileNameList”的文件,拷贝到目标路径下public boolean Paste(String path) {if (mCurFileNameList.size() == 0)return false;final String _path = path;//异步执行某个任务asnycExecute(new Runnable() {@Overridepublic void run() {for (FileInfo f : mCurFileNameList) {CopyFile(f, _path);}//通知操作变化mOperationListener.onFileChanged(Environment.getExternalStorageDirectory().getAbsolutePath());//粘贴之后,需要清空mCurFileNameListclear();}});return true;}//是否可以“粘贴”,mCurFileNameList有元素public boolean canPaste() {return mCurFileNameList.size() != 0;}//开始移动,标记“正在移动”,拷贝文件集合public void StartMove(ArrayList<FileInfo> files) {if (mMoving)return;mMoving = true;copyFileList(files);}//移动状态public boolean isMoveState() {return mMoving;}//能否移动,假设path为“C:/a/b”,f.filePath为“C:、/a/b/c/d.png”,不能移动//TODO 感觉不太靠谱啊,为啥不能移动到文件的上级目录呢?public boolean canMove(String path) {for (FileInfo f : mCurFileNameList) {if (!f.IsDir)continue;if (Util.containsPath(f.filePath, path))return false;}return true;}//清空当前文件集合public void clear() {synchronized (mCurFileNameList) {mCurFileNameList.clear();}}//停止移动,移动文件是异步执行,结束后有事件通知public boolean EndMove(String path) {if (!mMoving)return false;mMoving = false;if (TextUtils.isEmpty(path))return false;final String _path = path;asnycExecute(new Runnable() {@Overridepublic void run() {for (FileInfo f : mCurFileNameList) {MoveFile(f, _path);}mOperationListener.onFileChanged(Environment.getExternalStorageDirectory().getAbsolutePath());clear();}});return true;}public ArrayList<FileInfo> getFileList() {return mCurFileNameList;}//异步执行某个任务//android的类AsyncTask对线程间通讯进行了包装,提供了简易的编程方式来使后台线程和UI线程进行通讯:后台线程执行异步任务,并把操作结果通知UI线程。//可以参考http://blog.csdn.net/xufenghappy6/article/details/7343899private void asnycExecute(Runnable r) {final Runnable _r = r;new AsyncTask() {@Overrideprotected Object doInBackground(Object... params) {synchronized (mCurFileNameList) {_r.run();}if (mOperationListener != null) {mOperationListener.onFinish();}return null;}}.execute();}//某个路径是否被选中public boolean isFileSelected(String path) {synchronized (mCurFileNameList) {for (FileInfo f : mCurFileNameList) {if (f.filePath.equalsIgnoreCase(path))return true;}}return false;}//文件重命名public boolean Rename(FileInfo f, String newName) {if (f == null || newName == null) {Log.e(LOG_TAG, "Rename: null parameter");return false;}File file = new File(f.filePath);String newPath = Util.makePath(Util.getPathFromFilepath(f.filePath),newName);final boolean needScan = file.isFile();try {boolean ret = file.renameTo(new File(newPath));if (ret) {if (needScan) {mOperationListener.onFileChanged(f.filePath);}mOperationListener.onFileChanged(newPath);}return ret;} catch (SecurityException e) {Log.e(LOG_TAG, "Fail to rename file," + e.toString());}return false;}//删除若干文件,先copy文件集合,再异步执行删除操作,删除完成后,有通知public boolean Delete(ArrayList<FileInfo> files) {copyFileList(files);asnycExecute(new Runnable() {@Overridepublic void run() {for (FileInfo f : mCurFileNameList) {DeleteFile(f);}mOperationListener.onFileChanged(Environment.getExternalStorageDirectory().getAbsolutePath());clear();}});return true;}//删除1个文件protected void DeleteFile(FileInfo f) {if (f == null) {Log.e(LOG_TAG, "DeleteFile: null parameter");return;}File file = new File(f.filePath);boolean directory = file.isDirectory();if (directory) {for (File child : file.listFiles(mFilter)) {if (Util.isNormalFile(child.getAbsolutePath())) {DeleteFile(Util.GetFileInfo(child, mFilter, true));}}}file.delete();Log.v(LOG_TAG, "DeleteFile >>> " + f.filePath);}//执行1个文件的拷贝,如果文件是目录,拷贝整个目录,可能有递归Copyprivate void CopyFile(FileInfo f, String dest) {if (f == null || dest == null) {Log.e(LOG_TAG, "CopyFile: null parameter");return;}File file = new File(f.filePath);if (file.isDirectory()) {// directory exists in destination, rename itString destPath = Util.makePath(dest, f.fileName);File destFile = new File(destPath);int i = 1;while (destFile.exists()) {destPath = Util.makePath(dest, f.fileName + " " + i++);destFile = new File(destPath);}for (File child : file.listFiles(mFilter)) {if (!child.isHidden()&& Util.isNormalFile(child.getAbsolutePath())) {CopyFile(Util.GetFileInfo(child, mFilter, Settings.instance().getShowDotAndHiddenFiles()), destPath);}}} else {String destFile = Util.copyFile(f.filePath, dest);}Log.v(LOG_TAG, "CopyFile >>> " + f.filePath + "," + dest);}//移动文件,通过重命名的方式,移动的private boolean MoveFile(FileInfo f, String dest) {Log.v(LOG_TAG, "MoveFile >>> " + f.filePath + "," + dest);if (f == null || dest == null) {Log.e(LOG_TAG, "CopyFile: null parameter");return false;}File file = new File(f.filePath);String newPath = Util.makePath(dest, f.fileName);try {return file.renameTo(new File(newPath));} catch (SecurityException e) {Log.e(LOG_TAG, "Fail to move file," + e.toString());}return false;}//把文件集合copy到mCurFileNameList中,同步~private void copyFileList(ArrayList<FileInfo> files) {synchronized (mCurFileNameList) {mCurFileNameList.clear();for (FileInfo f : files) {mCurFileNameList.add(f);}}}}

小米开源文件管理器MiCodeFileExplorer-源码研究(4)-文件操作工具类FileOperationHelper相关推荐

  1. android+小米文件管理器源码,小米开源文件管理器MiCodeFileExplorer-源码研究(2)-2个单实例工具类...

    从本篇开始,讲解net.micode.fileexplorer.util工具包中的类. 这个包下的类,功能也比较单一和独立.很多代码的思想和实现,可以用于JavaWeb和Android等多种环境中. ...

  2. 支持小米java文件阅读器_小米开源文件管理器MiCodeFileExplorer-源码研究(0)-初步研究...

    2011年对着书本Android应用开发揭秘,写了2个月的HelloWorld. 现在想复习并深入,我没有耐心再去一点点地敲代码了. 4年前自己是个学生,实习,现在有工作,只能业余时间研究. 这一点是 ...

  3. 小米开源文件管理器MiCodeFileExplorer-源码研究(0)-初步研究

    2011年对着书本Android应用开发揭秘,写了2个月的HelloWorld. 现在想复习并深入,我没有耐心再去一点点地敲代码了. 4年前自己是个学生,实习,现在有工作,只能业余时间研究. 这一点是 ...

  4. android+小米文件管理器源码,小米开源文件管理器MiCodeFileExplorer-源码研究(1)-2个模型Model...

    上篇说到,把小米的Java代码整理成了5个包,其中1个是net.micode.fileexplorer.model. 这个包就2个模型类,最基本了,FileInfo和FavoriteItem. pac ...

  5. 小米开源文件管理器MiCodeFileExplorer-源码研究(1)-2个模型Model

    上篇说到,把小米的Java代码整理成了5个包,其中1个是net.micode.fileexplorer.model. 这个包就2个模型类,最基本了,FileInfo和FavoriteItem. pac ...

  6. 小米开源文件管理器MiCodeFileExplorer-源码研究(6)-媒体文件MediaFile和文件类型MimeUtils

    接着之前的第4篇,本篇的2个类,仍然是工具类. MediaFile,媒体文件,定义了一大堆的常量,真正的有用的方法就几个. isAudioFileType.isVideoFileType之类的. Mi ...

  7. Mark几款优秀的基于MPC开源播放器的源码供参考.

    SEP 11TH, 2016 2:00 PM MPC(Media Player Classic)是一款基于DirectShow由一名匈牙利大佬Gabest开发的一款开源播放器. 由于该项目基于GPL源 ...

  8. 小米开源文件管理器MiCodeFileExplorer-源码研究(3)-使用最多的工具类Util

    Util.java,使用最广泛~ 代码中很多地方,都写了注释说明~基本不需要怎么解释了~ package net.micode.fileexplorer.util;import java.io.Fil ...

  9. 小米开源文件管理器MiCodeFileExplorer-源码研究(8)-文件排序工具类FileSortHelper

    FileSortHelper的核心功能就是,对文件集合FileInfo排序. FileInfo有若干字段,根据字段定义了4种比较器Comparator. 调用示例:Collections.sort(L ...

最新文章

  1. python培训学费多少钱-培训python学费多少python学会得多少钱?
  2. SpringBoot学习之@Configuration注解和@Bean注解
  3. 二叉树的层序遍历 使用队列和不使用队列
  4. Thymeleaf引入公共片段方式
  5. Linux文件系统命令 cat
  6. orm java_Java 8 Friday:不再需要ORM
  7. 图像灰度变换及图像数组操作
  8. 走不远的共享滑板车!
  9. 实现Canvas2D绘图 使元素绕中心居中旋转
  10. board crt_容器编排系统K8s之Dashboard部署
  11. 企业微信SDK接口api调用代码
  12. Excel点击按钮隐藏指定行
  13. OpenGL ES 理解纹理与纹理过滤
  14. Matlab 绘制 BP 神经网络图
  15. k8s中对pod设置限制只设置了limits
  16. YOLOv2原文解读
  17. python怎么批量读取文件_python如何批量读取txt文件
  18. 【kubernetes/k8s源码分析】eviction机制原理以及源码解析
  19. 数据告诉你:疯狂联名的背后,藏着喜茶多大的商业野心?
  20. 2007年12月14日

热门文章

  1. unity2d 换装功能实现
  2. 我有一个页面a,在页面a中调用了一个组件,然后组件中要切换页面a的一块区域,该怎么实现?
  3. 数据集Cora、Citeseer、DBLP
  4. 网站标志设计元素之趋势
  5. 从学习C++到用C++做外挂
  6. 微信小程序开店的步骤
  7. 计算机二级C语言刷题笔记
  8. oracle中in和between的区别,in between与between 的用法区别
  9. 内网穿透(natapp、续断、花生壳)
  10. 详细讲解回溯算法(一)