Search code examples
javaandroidperformancefilesystemsinternal-storage

How to speed up File Storage Access?


I am trying to get a list of all Folders that contain MP3 Files on the user's Internal Storage.

Here is the recursive function that I am calling for this purpose -

public void listAllMusicFiles(String pathToDirectory) {
        String lastFolderPath = "";
        int mp3Count = 0;
        File f = new File(pathToDirectory);
        File[] files = f.listFiles();
        for (File inFile : files) {
            if (inFile.isDirectory()) {
                //reset last folder path
                lastFolderPath = "";
                Log.d("Directory ", inFile.getPath());
                listAllMusicFiles(inFile.getPath());
            } else {
                if (inFile.getAbsolutePath().endsWith(".mp3") || inFile.getAbsolutePath().endsWith(".MP3")) {
                    mp3Count++;
                    Log.wtf("MP3 Count", mp3Count + " ");

                    //add each folder only once
                    String folderName = inFile.getParentFile().getName();
                    String folderPath = inFile.getParentFile().getPath();
                    Log.e("FOUND in", folderPath);

                    //create a new Folder object
                    Folder currentFolder = new Folder(folderName, folderPath, mp3Count + "");

                    if (!lastFolderPath.equals(folderPath)) {
                        Log.d("NEW", folderPath);
                        lastFolderPath = folderPath;
                        folderArrayList.add(currentFolder);
                    } else {
                        Log.d("OLD", folderPath);
                        //find a Folder object in folderArrayList where the object's path matches current folderPath
                        for (Folder folder : folderArrayList) {
                            String currentPath = folder.getFolder_Path();
                            if (currentPath.equals(folderPath)) {
                                //found a match
                                //update count
                                folder.setFolder_Song_Count(mp3Count + "");
                            }
                        }
                    }
                }
            }
        }
    }

When I run this code on my device, I am able to list the required folders in a RecyclerView, but with a delay of about 6-7 seconds.

I have already moved this task into an AsyncTask, so that my UIThread does not hang because of this intensive operation.

But I am totally at a loss when it comes to improving File System Performance. Kindly help. Thanks !


Solution

  • Instead of storing currentFolder in an ArrayList and in the next step iterating through complete list to find that folder and updating the value, you can simply use HashMap like this

    HashMap<String, Folder> folders = new HashMap<>();
    
        public void listAllMusicFiles(String pathToDirectory) {
    
            int mp3Count = 0;
            File f = new File(pathToDirectory);
            File[] files = f.listFiles();
    
            Folder folder;
            String folderName, folderPath;
    
            for (File inFile : files) {
                if (inFile.isDirectory()) {
                    //reset last folder path
                    Log.d("Directory ", inFile.getPath());
                    listAllMusicFiles(inFile.getPath());
                } else {
                    if (inFile.getAbsolutePath().endsWith(".mp3") || inFile.getAbsolutePath().endsWith(".MP3")) {
                        mp3Count++;
                        Log.wtf("MP3 Count", mp3Count + " ");
    
                        //add each folder only once
                        folderName = inFile.getParentFile().getName();
                        folderPath = inFile.getParentFile().getPath();
    
                        Log.e("FOUND in", folderPath);
    
                        if (folders.containsKey(folderPath)) {
    
                            folder = folders.get(folderPath);
                            folder.setFolder_Song_Count(mp3Count + "");
                            folders.put(folderPath, folder);
                        } else {
    
                            folder = new Folder(folderName, folderPath, mp3Count + "");
                            folders.put(folderPath, folder);
                        }
    
                    }
                }
            }
        }