2012-08-11 85 views
1

我是Android新手,我试图开发包含搜索功能的文件浏览器。我使用的递归搜索功能可以在具有几个子文件夹和文件的文件夹中正常工作,但由于某些原因,它的EXTREMELY SLOW很慢,并且可能会在具有大量子文件夹和文件的文件夹中“强制关闭”,因为内存不足。我通过创建将放置结果的ArrayList来完成搜索,然后调用将填充列表的递归函数。 “路径”参数是搜索将从其开始的文件,“查询”是搜索查询。在android中创建一个快速文件搜索功能

ArrayList<File> result = new ArrayList<File>(); 
fileSearch(path, query, result); 

这是递归函数的样子:

private void fileSearch(File dir, String query, ArrayList<File> res) { 
    if (dir.getName().toLowerCase().contains(query.toLowerCase())) 
     res.add(dir); 
    if (dir.isDirectory() && !dir.isHidden()) { 
     if (dir.list() != null) { 
      for (File item : dir.listFiles()) { 
       fileSearch(item, query, res); 
      } 
     } 
    } 
} 

如果有人能指出我进行更快和/或更有效的文件搜索的一种方式,我真的很感激。

编辑:

这是我试图做的AsyncTask工作:

private class Search extends AsyncTask<File, Integer, Void> { 

    String query; 
    ArrayList<File> result = new ArrayList<File>(); 

    public Search(String query){ 
     this.query = query; 
     setTitle("Searching"); 
    } 

    @Override 
    protected Void doInBackground(File... item) { 
     int count = item.length; 
     for (int i = 0; i < count; i++) { 
      fileSearch(item[i], query, result); 
      publishProgress((int) ((i/(float) count) * 100)); 
      // Escape early if cancel() is called 
      if (isCancelled()) break; 
     } 
     return null; 
    } 

    protected void onProgressUpdate(Integer... progress) { 
     setProgress(progress[0]); 
    } 

    protected void onPostExecute() { 
     searchResults = new ListItemDetails[result.size()]; 
     for (int i = 0; i < result.size(); i++) { 
      File temp = result.get(i); 
      if (temp.isDirectory()) 
       searchResults[i] = new ListItemDetails(temp.getAbsolutePath(), 
         R.drawable.folder, temp.lastModified(), temp.length()); 
      else { 
       String ext; 
       if (temp.getName().lastIndexOf('.') == -1) 
        ext = ""; 
       else 
        ext = temp.getName().substring(
          temp.getName().lastIndexOf('.')); 
       searchResults[i] = new ListItemDetails(temp.getAbsolutePath(), 
         getIcon(ext), temp.lastModified(), temp.length()); 
      } 
     } 
     finishSearch(); 
    } 

} 

public void finishSearch() { 
    Intent intent = new Intent(this, SearchResults.class); 
    startActivity(intent); 
} 

到finishSearch()的调用,这样我可以创造的意图,表明在其他活动的结果。任何想法,建议,提示?在此先感谢

+1

强制关闭可能是由于执行上的主线程的代码,使用的AsyncTask – nandeesh 2012-08-11 19:23:20

+0

可以为用户提供教程或有关的AsyncTask的一些信息链接? – kiko283 2012-08-11 21:08:49

+0

在这里检查http://developer.android.com/reference/android/os/AsyncTask.html – nandeesh 2012-08-11 21:12:23

回答

4

这可能是你打symbolic links并进入一个不定式的循环与您的搜索功能和耗尽可用内存到您的应用程序。

我建议你保留一个单独的列表,包含你访问过的目录的规范路径(File.getCanonicalPath()),并避免一遍又一遍地访问它们。

+0

这是一个非常好的建议,尽管我放弃了浏览器应用程序(因为您看到没有接受的答案),我真的很喜欢你的建议,upvoted和评论所以其他人们也可能会觉得它很有用。 – kiko283 2014-01-06 06:15:52

+0

@ kiko283非常感谢但是我认为如果它覆盖了你的问题,不管你用你的应用做了什么,你仍然应该接受这个答案。干杯。 – auselen 2014-01-06 11:26:25

+0

我还没有测试过它是否会起作用,所以我不想误导人们。希望你能理解。 – kiko283 2014-01-07 01:17:43

2

为什么不使用Apache Commons IO?它有一些处理搜索的功能。

我还建议使用方法FileUtils.listFiles,它将文件夹,搜索查询和目录过滤器作为参数。

以下示例返回按照正则表达式匹配的所有文件路径的列表。尝试添加它doInBackground您的AsyncTask的

Collection files = FileUtils.listFiles(new File(yourRootPath), 
        new RegexFileFilter(searchQuery), 
        DirectoryFileFilter.DIRECTORY); 
+0

我喜欢这种方法,重用现有的库总是不错的做法。 – 2013-09-17 17:14:59

+0

listFiles是否递归?我相信你想'iterateFiles'。 – 2013-09-18 12:07:35

+0

另一个很好的建议,谢谢 – kiko283 2014-01-06 06:17:08

0

你看着Lucene的?

它特别设计用于索引和查询大量的自由文本文档,因此许多I/O流式处理和索引任务已经为您解决。如果删除递归并以纯迭代方式使用Lucene索引执行文档索引,则内存问题可能会减轻。

看看这个线程:

Lucene in Android