2016-01-13 44 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 []'然后排序它...我很抱歉,但实际上这会比我的方法花费更长的时间,因为我可以在第一次迭代名称时存储最高值。 –

相关问题