2016-01-13 29 views
1

給定一個File dir我需要找到的最高的數字文件名(如果有的話)從目錄中獲得最高的數字文件名(INT) - Java的

我的方法:

// get the highest numeric file name(as int) from given directory 
public static final int getHighestNumericFileName(File dir) { 
    int result = -1; 

    for (File f : dir.listFiles()) { 
     String name = f.getName(); 
     name = name.substring(0, name.indexOf('.')); 
     if (StringUtils.isNumeric(name)) { 
      int val = Integer.parseInt(name); 
      if (val > result) 
       result = val; 
     } 
    } 

    return result; 
} 

考慮文件夾中的文件數可能會相當大(300k +),我擔心的是與性能有關。

這是一個可以接受的解決方案嗎?還有更好的方法嗎?

+0

相關的文件夾內的所有文件(即你需要檢查所有文件或只有遵循特定名稱模式的文件)? –

+0

@ThiagoPorciúncula所有完整的數字名稱是遊戲,其餘的都沒有興趣...我實際上希望有一些聰明的正則表達式的解決方案,但不能想到任何東西... –

+1

那麼,如果你需要使用文本文件來管理300K它變得真正愚蠢。數據庫將是一個更好的主意 –

回答

2

您可以使用Java NIO 7的DirectoryStream使用過濾器,以確保你忽略不是與您相關的文件,通過您的文件中去。

這裏是過濾器:

class NumericFilter implements DirectoryStream.Filter<Path> { 

    private static final Pattern PATTERN = Pattern.compile("\\d+|\\d+\\..*"); 

    @Override 
    public boolean accept(Path entry) throws IOException { 
     return PATTERN.matcher(entry.getFileName().toString()).matches(); 
    } 

} 

這裏是使用它的代碼:

try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(dir), new NumericFilter())) { 
    for (Path path : stream) { 
     // do what you want 
    } 
} 

這隻會經過文件具有完全數字的名字(有或沒有任何擴展名)。


只是爲了記錄在案,這裏是一個稍微簡單的做同樣的與Java 8路:

final Pattern pattern = Pattern.compile("\\d+\\..*"); 
try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(dir), 
     entry -> pattern.matcher(entry.getFileName().toString()).matches())) { 
    for (Path path : stream) { 
     // do what you want 
    } 
} 
+0

看起來像這樣可以工作......我假設'「[0-9] *。*」'這將考慮到任何非數字後綴,因此將其更改爲'「[0-9]。*」'應該做的伎倆。 –

+0

@DimaMaligin'[0-9]。*'只會匹配其名稱上的單個數字的文件。我正在研究一個新的glob。 –

+0

''[0-9] +。*「'然後 –

1

我建議你排序文件,並採取第一個條目或最後一個條目。

FileFilter fileFilter = new WildcardFileFilter("\\d+.txt"); 
File[] files = dir.listFiles(fileFilter); 
Arrays.sort(files);//sorts lexicographically 
+0

我不能假設所有的文件都是數字命名的,在這種情況下,病態仍然必須迭代跳過非數字的後分類。並且無法知道是否有數字名稱,在這種情況下,它將迭代所有這些數字... –

+0

您可以使用正則表達式篩選器來僅獲取其中包含數字的文件。 –

+0

非常好...似乎可以工作。任何關於實施非詞典排序的建議? Id寧願避免自我實現排序... –

0

對於大量的數字,排序它們的最佳方法是使用Heap Sort。例如

int[] yourFiles = {} //Puts all file names in array 
HeapSort.sort(yourFiles); 
result = yourFiles[yourFilens.length-1]; 

堆排序

public class HeapSort 
{ 
    private static int[] a; 
    private static int n; 
    private static int left; 
    private static int right; 
    private static int largest; 


    public static void buildheap(int []a) 
    { 
     n=a.length-1; 
     for(int i=n/2;i>=0;i--) 
     { 
      maxheap(a,i); 
     } 
    } 

    public static void maxheap(int[] a, int i) 
    { 
     left=2*i; 
     right=2*i+1; 
     if(left <= n && a[left] > a[i]) 
     { 
      largest=left; 
     } 
     else 
     { 
      largest=i; 
     } 

     if(right <= n && a[right] > a[largest]) 
     { 
      largest=right; 
     } 

     if(largest!=i) 
     { 
      exchange(i,largest); 
      maxheap(a, largest); 
     } 
    } 

    public static void exchange(int i, int j) 
    { 
     int t=a[i]; 
     a[i]=a[j]; 
     a[j]=t; 
    } 

    public static void sort(int[] a0) 
    { 
     a=a0; 
     buildheap(a); 

     for(int i=n;i>0;i--) 
     { 
      exchange(0, i); 
      n=n-1; 
      maxheap(a, 0); 
     } 
    } 
} 

這方面的一個例子實現將是。

import java.util.Arrays; 
public class Test 
{ 
    public static void main(String[] args) 
    { 
     int[] test = {1,5,6,8,6,41}; 
     HeapSort.sort(test); 
     System.out.println(Arrays.toString(test)); 
    } 
} 
+0

@UmaKanth我會給你它更容易,但堆排序非常大的數據量更有效 – Dan

+1

我仍然需要遍歷目錄中的所有文件檢查if該名稱是數字粘在另一個'int []'然後排序它...我很抱歉,但實際上這會比我的方法花費更長的時間,因爲我可以在第一次迭代名稱時存儲最高值。 –