簡體   English   中英

如何在Windows上加快Java遞歸文件搜索?

[英]How can I speed up my Java recursive file search on Windows?

我正在使用Java 8搜索文件目錄並提取音樂文件。 當我在Linux(Debian Wheezy)上運行代碼時,它會在20秒鍾左右完成。 但是,當我在Windows 8.1(同一台機器!)上運行相同的代碼時,要花費非常長的時間,時間如此之長,以至於它實際上是不可用的。 我已經確定該過程正在按預期進行,只是非常緩慢。 在Linux變體找到所有2500個文件的時候,Windows變體找到了大約100個。

這是代碼:

public int List(String path) throws InterruptedException, IOException {
    //Linux Variant
    if (HomeScreen.os.equals("Linux")) {
        File root = new File(path);
        File[] list = root.listFiles();
        Arrays.sort(list);
        if (list == null) {
            return 0;
        }

        for (File f : list) {
            if (f.isDirectory()) {
                List(f.getAbsolutePath());

            } else if (f.isFile()) {
                String outPath = f.getAbsolutePath();
                try {
                    String ext = outPath.substring(outPath.lastIndexOf(".") + 1);
                    if (ext.equals("wma") || ext.equals("m4a") || ext.equals("mp3")) {
                        String fulltrack = outPath.substring(outPath.lastIndexOf("Music/") + 6);
                        lm.addElement(fulltrack);
                        numbers++;
                    }
                } catch (Exception e) {
                    System.out.println(outPath + " is not a valid file!!!!!");
                }
                HomeScreen.Library.setModel(lm);

            }

        }
    //Windows variant
    } else if (HomeScreen.os.equals("Windows 8.1")){
        System.out.println("Using " + HomeScreen.os + " methods...");
        File root = new File(path);
        File[] list = root.listFiles();
        Arrays.sort(list);
        if (list == null) {
            return 0;
        }

        for (File f : list) {
            if (f.isDirectory()) {
                List(f.getAbsolutePath());

            } else if (f.isFile()) {
                String outPath = f.getAbsolutePath();
                try {
                    String ext = outPath.substring(outPath.lastIndexOf(".") + 1);
                    if (ext.equals("wma") || ext.equals("m4a") || ext.equals("mp3")) {
                        String fulltrack = outPath.substring(outPath.lastIndexOf("Music/") + 9);
                        lm.addElement(fulltrack);
                        numbers++;
                    }
                } catch (Exception e) {
                    System.out.println(outPath + " is not a valid file!!!!!");
                }
                HomeScreen.Library.setModel(lm);

            }

        }
    }
    return numbers;
}

我對Java還是很陌生,所以我不確定如何為Windows優化代碼。 有什么辦法可以加快這種速度,還是Windows用戶注定要去喝咖啡並等待負載增加?

順便說一句,我在使用Windows時將此方法放在線程中,以便可以在等待時完成其他操作,但這絕對不是理想的解決方案。 要搜索的驅動器是一個7200 rpm的HDD,並且安裝了8GB RAM。

嘗試使用新的Java 8流API,它可以讓您在一個循環中執行所有操作(對每個過濾器進行排序)! 與並行:

這是您更改后的代碼(您可能需要修復我確實有的某些部分,例如HomeScreen)

        Arrays.asList(root.listFiles())
                                   .parallelStream()
                                   .filter(file -> file != null)
                                   .forEach(file -> {
                                       if (file.isDirectory())
                                       {
                                           List(file.getAbsolutePath());
                                       }
                                       else if (file.isFile())
                                       {
                                           String outPath = file.getAbsolutePath();
                                           try
                                           {
                                               String ext = outPath.substring(outPath.lastIndexOf(".") + 1);
                                               if (ext.equals("wma") || ext.equals("m4a") || ext.equals("mp3"))
                                               {
                                                   String fulltrack = outPath.substring(outPath.lastIndexOf("Music/") + 9);
                                                   lm.addElement(fulltrack);
                                                   numbers++;
                                               }
                                           } catch (Exception e)
                                           {
                                               System.out.println(outPath + " is not a valid file!!!!!");
                                           }
                                           HomeScreen.Library.setModel(lm);
                                       }
                                   });

正如在對Lorenzo Boccaccia所鏈接的問題的評論中所建議的那樣,我將選擇newDirectoryStream 它一個接一個地返回文件,應該更快。

我也會考慮使用多線程。 使用單個線程,您幾乎一直都在等待磁盤。 現代磁盤能夠處理多個未決請求,因此使用2-4個線程應該會有所幫助。


旁注:沒有理由針對Linux和Windows編寫不同的代碼。 可能需要進行一些細微的更改,但是應該使用一些小的輔助方法來進行處理。

絕對不要寫像

if (HomeScreen.os.equals("Linux")) {
    ...
} else if (HomeScreen.os.equals("Windows 8.1")) {
    ...
}

如果是“ Windows 8.2”怎么辦?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM