Android本地文件管理器思路解析一一增删改查具体实现

Posted 化作孤岛的瓜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android本地文件管理器思路解析一一增删改查具体实现相关的知识,希望对你有一定的参考价值。

花了一天的时间撸完了android本地文件管理器~!!GitHub下载地址为:PumpkinFileManager

南瓜文件管理器1.0.

功能列表:
1: 实现了在ListView中浏览本地所有文件.
2: 实现了对文件的增(新建文件夹)
3: 删(删除文件或文件夹).
4: 改(重命名以及复制粘贴文件).
5: 查(对当前路径下的递归查询).
6: 排(对显示在listView中的文件按时间,大小或文件名排序).


整体思路:

大概的思路是首先遍历本地所有文件的根目录,然后通过使用栈结构存储文件路径,因为出栈入栈的特性很适合处理随着用户操作不断推出存入的文件路径,之后增删改查的具体实现在下文都有详细解释以及缩略图,总共花费大概10个小时(折腾了好久Github..sad),也是完成了周末の任务2333


具体实现:

1: 实现了在ListView中浏览本地所有文件.


实现原理:

使用了栈结构保存当前的文件路径,每一次点击文件夹,就会把当前文件名推入栈组成新的文件路径。

实现得到当前栈路径的方法:

    //得到当前栈路径的String
    private String getPathString() 
        Stack<String> temp = new Stack<>();
        temp.addAll(nowPathStack);
        String result = "";
        while (temp.size() != 0) 
            result = temp.pop() + result;
        
        return result;
    
在item的onItemClick方法中将点击的文件名推入栈:

                //如果是文件夹
                // 清除列表数据
                // 获得目录中的内容,计入列表中
                // 适配器通知数据集改变
                nowPathStack.push("/" + file.getName());
                showChangge(getPathString());

显示改变路径之后的listview文件列表:

    //显示改变data之后的文件数据列表
    private void showChangge(String path) 
        showtv.setText(path);
        files = new File(path).listFiles();
        data.clear();
        for (File f : files) 
            data.add(f);
        
        files = fileAdapter.setfiledata(data);
    


2: 实现了对文件的增(新建文件夹)


实现原理:

根据当前路径,以及通过dialog得到的用户输入的文件名执行新建文件夹的操作:

    /**
     * 创建新文件夹
     */
    private void doCreateNewFolder() 
        mydialog = new AlertDialog.Builder(MainActivity.this).create();
        mydialog.show();
        mydialog.getWindow().setContentView(R.layout.newfloder_dialog);
        mydialog.setView(new EditText(MainActivity.this));
        //加入下面两句以后即可弹出输入法
        mydialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
        mydialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
        newfloder_name = (EditText) mydialog.getWindow().findViewById(R.id.newfloder_name);

        mydialog.getWindow()
                .findViewById(R.id.newfloder_cancle)
                .setOnClickListener(new View.OnClickListener() 
                    @Override
                    public void onClick(View v) 
                        mydialog.dismiss();
                    
                );
        mydialog.getWindow()
                .findViewById(R.id.newfloder_create)
                .setOnClickListener(new View.OnClickListener() 
                    @Override
                    public void onClick(View v) 
                        String name =  newfloder_name.getText().toString();
                        if (name != null) 
                            File folder = new File(getPathString() + "/" + name);
                            folder.mkdirs();
                            if (folder.exists()) 
                                Toast.makeText(MainActivity.this,"文件:"+name + " 创建成功",Toast.LENGTH_SHORT).show();
                                showChangge(getPathString());
                                mydialog.dismiss();
                            
                        

                    
                );
    



3: 删(删除文件或文件夹).


在adapter中直接执行删除操作:

        /**
         * 删除
         */
        private void doRemove() 
            final File file = filedata.get(position);
             judgeAlertDialog(context, "提醒", "你确认删除" + file.getName() + "吗(不可逆)?", new DialogInterface.OnClickListener() 
                 @Override
                 public void onClick(DialogInterface dialog, int which) 
                     deleteDir(file);
                     filedata.remove(file);
                     notifyDataSetChanged();
                     showToast(file.getName() + " 删除成功");
                 
             , null);
        



4: 改(重命名以及复制粘贴文件).

      

实现原理:

1、重命名

在adapter中直接执行重命名操作:

        /**
         * 重命名
         */
        private void doRename() 
            showToast("重命名" + position);
            RenameFileDialog dialog = new RenameFileDialog(context, filedata, position);
            dialog.setOnFileRenameListener(new RenameFileDialog.OnFileRenameListener() 
                @Override
                public void onFileRenamed(boolean success) 
                    String message = null;
                    if (filedata.get(position).isFile()) 
                        message = "文件";
                     else 
                        message = "文件夹";
                    
                    if (success) 
                        message += "重命名成功";
                     else 
                        message += "重命名失败";

                    
                    showToast(message);
                
            );
            dialog.show();
            setfiledata(filedata);
        
2、复制文件:

如下图所示:

使用了简单的回调执行复制操作,在FileAdapter定义复制接口,然后在MainActivity中实现接口,并通过setListener将自身实例传入FileAdapter,从而实现在FileAdapter中执行复制操作。

MainActivity中的粘贴操作实现如下:

    /**
     * 复制或粘贴
     */
    private void doPaste() 
        File newFile = new File(getPathString()+"/"+watingCopyFile.getName());
        if (watingCopyFile.equals(null)) 
            Snackbar.make(findViewById(R.id.main_view), "当前粘贴板为空,不能粘贴", Snackbar.LENGTH_SHORT).show();
         else 
            if (watingCopyFile.isFile()&&watingCopyFile.exists())
                try 
                    FileInputStream fis = new FileInputStream(watingCopyFile);
                    FileOutputStream fos = new FileOutputStream(newFile);
                    int len = -1;
                    long contentSize = watingCopyFile.length();
                    long readed = 0;
                    byte[] buff = new byte[8192];
                    while ((len=fis.read(buff))!=-1)
                        //写文件
                        fos.write(buff,0,len);
                        readed+=len;
                        //发布进度
                    
                    fos.flush();
                    fis.close();
                    fos.close();
                 catch (IOException e) 
                    e.printStackTrace();
                 finally 
                
            
            if (newFile.exists()) 
                Toast.makeText(MainActivity.this,"复制" + newFile.getName() + "成功",Toast.LENGTH_SHORT).show();
                fileAdapter.notifyDataSetChanged();
            
        

    



5: 查(对当前路径下的递归查询).


实现原理:

        data = new ArrayList<>();
        searchfilemap = new HashMap<>();

          searchByPath(path);

        if (searchfilemap.size() > 0) 
            //取出map中数据,赋值给data
            Object[] list = searchfilemap.entrySet().toArray();
            for (int i = 0; i < searchfilemap.size(); i++) 
                data.add(new File(list[i].toString()));
            
        
通过递归查找本地所有文件,寻找匹配输入字符query的文件名的文件,并全部显示在listview上。

递归方法:

    /**
     * 通过路径递归查找文件
     * @param path
     */
    private void searchByPath(String path) 
        File[] files = new File(path).listFiles();
        filenum += files.length;
        publishProgress(filenum);
        for (int i = 0; i < files.length; i++) 
            File f = files[i];
            if (f.isDirectory()) 
                searchByPath(path + "/" + f.getName());
             else 
                if (f.getName().contains(query)) 
                    searchfilemap.put(files[i], files[i].getName());
                
            
        
    


6:排(对显示在listView中的文件按时间,大小或文件名排序)


实现方法使用杨羿的方式,通过对文件种类进行分类比较实现排序:

首先需要一个格式工厂类:

public class FileSortFactory 
    public static final int SORT_BY_FOLDER_AND_NAME = 1;
    public static final int SORT_BY_FOLDER_REVERSE_AND_NAME = 2;
    public static final int SORT_BY_FOLDER_AND_NAME_REVERSE = 3;
    public static final int SORT_BY_FOLDER_REVERSE_AND_NAME_REVERSE = 4;
    public static final int SORT_BY_FOLDER_AND_SIZE = 5;
    public static final int SORT_BY_FOLDER_REVERSE_AND_SIZE = 6;
    public static final int SORT_BY_FOLDER_AND_SIZE_REVERSE = 7;
    public static final int SORT_BY_FOLDER_REVERSE_AND_SIZE_REVERSE = 8;
    public static final int SORT_BY_FOLDER_AND_TIME = 9;
    public static final int SORT_BY_FOLDER_REVERSE_AND_TIME = 10;
    public static final int SORT_BY_FOLDER_AND_TIME_REVERSE = 11;
    public static final int SORT_BY_FOLDER_REVERSE_AND_TIME_REVERSE = 12;


    public static Comparator<File> getWebFileQueryMethod(
            int method) 
        switch (method) 
            case SORT_BY_FOLDER_AND_NAME:
                return new SortByFolderAndName(true, true);
            case SORT_BY_FOLDER_REVERSE_AND_NAME:
                return new SortByFolderAndName(false, true);
            case SORT_BY_FOLDER_AND_NAME_REVERSE:
                return new SortByFolderAndName(true, false);
            case SORT_BY_FOLDER_REVERSE_AND_NAME_REVERSE:
                return new SortByFolderAndName(false, false);
            case SORT_BY_FOLDER_AND_SIZE:
                return new SortByFolderAndSize(true, true);
            case SORT_BY_FOLDER_REVERSE_AND_SIZE:
                return new SortByFolderAndSize(false, true);
            case SORT_BY_FOLDER_AND_SIZE_REVERSE:
                return new SortByFolderAndSize(true, false);
            case SORT_BY_FOLDER_REVERSE_AND_SIZE_REVERSE:
                return new SortByFolderAndSize(false, false);
            case SORT_BY_FOLDER_AND_TIME:
                return new SortByFolderAndTime(true, true);
            case SORT_BY_FOLDER_REVERSE_AND_TIME:
                return new SortByFolderAndTime(false, true);
            case SORT_BY_FOLDER_AND_TIME_REVERSE:
                return new SortByFolderAndTime(true, false);
            case SORT_BY_FOLDER_REVERSE_AND_TIME_REVERSE:
                return new SortByFolderAndTime(false, false);
            default:
                break;
        
        return null;

    

之后再对应的具体排序方法类(这里只列出一种):

public class SortByFolderAndName implements Comparator<File> 

	boolean first;
	boolean second;

	public SortByFolderAndName(boolean first,boolean second) 
		this.first = first;
		this.second = second;
	

	@Override
	public int compare(File lhs, File rhs) 
		if (first) 
			if (!lhs.isFile() && rhs.isFile()) 
				return -1;
			
			if (lhs.isFile() && !rhs.isFile()) 
				return 1;
			
		 else 
			if (!lhs.isFile() && rhs.isFile()) 
				return 1;
			
			if (lhs.isFile() && !rhs.isFile()) 
				return -1;
			
		

		if (second) 
			if (!(lhs.isFile() ^ rhs.isFile())) 
				return lhs.getName().compareTo(rhs.getName());
			
		 else 
			if (!(lhs.isFile() ^ rhs.isFile())) 
				return -lhs.getName().compareTo(rhs.getName());
			
		

		return 0;
	




最后,在Adapter中通过排序方法实现对所有文件的排序:

    /**
     * 将文件列表排序
     */
    private void sort() 
        Collections.sort(this.filedata, FileSortFactory.getWebFileQueryMethod(sortWay));
    



*************************************(づ ̄ 3 ̄)づ完结收工****************************************************************

以上,就是这两天の战斗成果总结了。

话说这两天碰到的坑实在太多,先是Github提交以后不显示进度点,折腾了好久才发现是邮箱写错了!

编码过程中倒是没有太大的难点,虽然这个项目比较简单但是也把以前学过的东西很好的复习了一遍。

但是还是平时练得太少了!!!很多东西很久不用就忘掉了~!

orz,哎好想找个实习充实自己~~~2333(残念脸)

以上是关于Android本地文件管理器思路解析一一增删改查具体实现的主要内容,如果未能解决你的问题,请参考以下文章

android中如何对xml中存储的数据进行增删改查?求完整的例子。谢谢

在 Android 中解析本地 XML 文件

java使用sax解析xml

跪求 一个Android 里一个本地Json文件的解析,要完

Android Studio App开发中数据库SQLite的解析及实战使用(包括创建数据库,增删改查,记住密码等 附源码必看)

Linux的基本优化