2016-01-13 3 views
1

Учитывая File dir Мне нужно найти наибольшее числовое имя файла (если таковые существуют)Получить наибольшее числовое имя файла (как межд) из каталога - 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; 
} 

Учитывая количество файлов в папке может быть довольно большим (300 Кбайт), моя проблема связана с производительностью.

Действительно ли это приемлемое решение? И есть ли лучший способ?

+0

ли все файлы в папке соответствующего (то есть вам нужно проверять все файлы или только файлы, которые следуют определенной схеме имен)? –

+0

@ ThiagoPorciúncula Все полностью числовые имена - это игра, остальные не представляют интереса ... Я действительно надеялся на какое-то умное решение регулярных выражений, но не мог подумать ни о чем ... –

+1

Ну, если вам нужно использовать текстовые файлы для управления 300 КБ становится настоящим глупо. База данных была бы лучшей идеей –

ответ

2

Вы можете использовать Java 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]. * "' Should Покажи фокус. –

+0

@DimaMaligin '[0-9]. *' Будет соответствовать только файлам с одним номером на его имени. Я работаю над новым глотком. –

+0

Как насчет '" [0-9] +. * "' Then –

1

Я бы предложил вам отсортировать файлы и выполнить первую запись или последнюю запись.

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

Я не могу предположить, что все файлы численно названы, и в этом случае им еще нужно итерации, чтобы пропустить не числовые после Сортировать. И нет никакого способа узнать, есть ли числовые имена вообще, и в этом случае он будет перебирать все из них ... –

+0

Вы можете использовать фильтр регулярных выражений, чтобы получать только файлы с числовыми в нем. –

+0

Очень приятно ... похоже, что он может работать. Любое предложение по внедрению не-лексикографического рода? Идентификатор скорее избегает самоисследовательной сортировки ... –

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 Я дам вам это проще, но heapsort намного эффективнее при сортировке очень больших объемов данных – Dan

+1

Мне все равно придется перебирать все файлы в каталоге, проверяем, если имя - это числовое вставить его в другой 'int []', а затем отсортировать его ...Извините, но на самом деле это займет больше времени, чем мой подход, так как я могу просто сохранить наивысшую ценность при повторении имен в первый раз. –