2014-12-04 3 views
1

Я пытаюсь написать программу, которая удалит все повторяющиеся файлы в каталоге. В настоящее время он способен обнаруживать дубликаты, но мой код удаления, похоже, не работает (Files.delete() возвращает false). Может ли кто-нибудь сказать мне, почему это так?Не удается удалить файлы в заданном каталоге

Текущий код:

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.lang.SecurityManager; 

public class Duplicate { 
    @SuppressWarnings("resource") 
    public static boolean isDuplicate(File a, File b) throws IOException { 
     FileInputStream as = new FileInputStream(a); 
     FileInputStream bs = new FileInputStream(b); 
     while(true) { 
      int aBytes = as.read(); 
      int bBytes = bs.read(); 
      if(aBytes != bBytes) { 
       return false; 
      } else if(aBytes == -1) { 
       System.out.println("Duplicate found: "+a.getName()+", "+b.getName()); 
       return true; 
      } 
     } 
    } 

    public static void main(String[] args) throws IOException { 
     File dir = new File(System.getProperty("user.dir")); 
     File[] files = dir.listFiles(); 
     for(int i = 0; i < files.length; i++) { 
      for(int j = i+1; j < files.length; j++) { 
       if(isDuplicate(files[i], files[j])) { 
        String filePath = System.getProperty("user.dir").replace("\\", "/")+"/"+files[i].getName(); 
        System.out.println("Deleting "+filePath); 
        File f = new File(filePath); 
        if(f.delete()) 
         System.out.println(filePath+" deleted successfully"); 
        else 
         System.out.println("Could not delete "+filePath); 
       } 
      } 
     } 
    } 
} 
+1

В 'if (isDuplicate (файлы [i], файлы [j]))' почему вы воссоздаете файловый объект? Просто удалите один из дубликатов, например 'files [i] .delete()' – Athafoud

+0

Сделайте себе одолжение и используйте java.nio.file. По крайней мере, исключение возникает, если удаление файла не выполняется ... – fge

ответ

3

ли вы закрываете потоки файлов? Было бы разумно, что он вернет false, если файл открыт.

3

Помимо проблемы с ресурсами (что, безусловно, объясняет, почему вы не можете удалить), проблема в том, что вы не будете знать, почему удаление не удалось - на самом деле, с File у вас нет средств знать вообще.

Вот эквивалентная программа, написанная с java.nio.file с управлением ресурсами:

public final class Duplicates 
{ 

    private Duplicates() 
    { 
     throw new Error("nice try!"); 
    } 

    private static boolean duplicate(final Path path1, final Path path2) 
     throws IOException 
    { 
     if (Files.isSameFile(path1, path2)) 
      return true; 

     final BasicFileAttributeView view1 
      = Files.getFileAttributeView(path1, BasicFileAttributeView.class); 
     final BasicFileAttributeView view2 
      = Files.getFileAttributeView(path2, BasicFileAttributeView.class); 

     final long size1 = view1.readAttributes().size(); 
     final long size2 = view2.readAttributes().size(); 

     if (size1 != size2) 
      return false; 
     try (
      final FileChannel channel1 = FileChannel.open(path1, 
       StandardOpenOption.READ); 
      final FileChannel channel2 = FileChannel.open(path2, 
       StandardOpenOption.READ); 
     ) { 
      final ByteBuffer buf1 
       = channel1.map(FileChannel.MapMode.READ_ONLY, 0L, size1); 
      final ByteBuffer buf2 
       = channel2.map(FileChannel.MapMode.READ_ONLY, 0L, size1); 

      // Yes, this works; see javadoc for ByteBuffer.equals() 
      return buf1.equals(buf2); 
     } 
    } 

    public static void main(final String... args) 
     throws IOException 
    { 
     final Path dir = Paths.get(System.getProperty("user.dir")); 
     final List<Path> list = new ArrayList<>(); 

     for (final Path entry: Files.newDirectoryStream(dir)) 
      if (Files.isRegularFile(entry)) 
       list.add(entry); 

     final int size = list.size(); 

     for (int i = 0; i < size; i++) 
      for (int j = i + 1; j < size; j++) 
       try { 
        if (duplicate(list.get(i), list.get(j))) 
         Files.deleteIfExists(list.get(j)); 
       } catch (IOException e) { 
        System.out.printf("Aiie... Failed to delete %s\nCause:\n%s\n", 
         list.get(j), e); 
       } 
    } 
} 

Примечание: лучшая стратегия, вероятно, будет создать каталог, в котором будет двигаться все дубликаты вы обнаружить; Когда это будет сделано, просто удалите все файлы в этом каталоге, а затем сам каталог. См. Files.move().