0

I have a method which gets files list from given path. but if I give D or C it tooks ~20 mins to get all files list. Windows file search ~1.5 mins. I searched multithreading vs but couldn't find useful solution.

private static List<File> getFiles(String path) {

    File[] arrayOfFile1;
    File root = new File(path);

    File[] list = root.listFiles();

    if (list == null)
        return null;

    int j = (arrayOfFile1 = list).length;
    for (int i = 0; i < j; ++i) {
        File f = arrayOfFile1[i];

        if ((f.isDirectory()) && (!(f.getName().equals(".svn")))) {
            getFiles(f.getAbsolutePath());
        } else if (!(f.getName().equals(".svn"))) {
            sourceFiles.add(f.getAbsoluteFile());
        }
    }
    return sourceFiles;
}
Mgnfcnt
  • 129
  • 3
  • 11
  • 1
    Can you check how much time it takes using the solution suggested here http://stackoverflow.com/questions/2056221/recursively-list-files-in-java – hmashlah Mar 13 '14 at 20:47
  • 5
    NB: windows is probably indexing in the background –  Mar 13 '14 at 20:48
  • "if I give D or C" <-- what do you mean? – fge Mar 13 '14 at 20:53
  • D:\ and C:\ path (top disk directory) i gave these because they have too many files – Mgnfcnt Mar 13 '14 at 21:06
  • Accessing large number of files takes a long time if you have a HDD instead of an SSD as the heads need to physically move to where each files is on disk. Windows search can use an index which avoid shaving to access so many file. – Peter Lawrey Mar 13 '14 at 22:05

2 Answers2

1

If you use Java 7, use a FileVisitor:

// "final" is necessary for below
final List<File> sourceFiles = new ArrayList<>();

Files.walkFileTree(Paths.get(path), new FileVisitor<Path>()
{
    @Override
    public FileVisitResult preVisitDirectory(final Path dir,
        final BasicFileAttributes attrs)
        throws IOException
    {
        return ".svn".equals(dir.getFileName())
            ? FileVisitResult.SKIP_SUBTREE
            : FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(final Path file,
        final BasicFileAttributes attrs)
        throws IOException
    {
        sourceFiles.add(file.getAbsolutePath().toFile());
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(final Path file,
        final IOException exc)
        throws IOException
    {
        throw exc;
    }

    @Override
    public FileVisitResult postVisitDirectory(final Path dir,
        final IOException exc)
        throws IOException
    {
        return FileVisitResult.CONTINUE;
    }
});
fge
  • 119,121
  • 33
  • 254
  • 329
  • First of all thank you for your help. While i wanna run this code it gives Exception in thread "main" java.nio.file.AccessDeniedException: error. – Mgnfcnt Mar 13 '14 at 21:16
  • 1
    You have to love the new API, no? A meaningful exception name instead of `FileNotFoundException` ;) It means what it means: you try and access a path which you have no access to. Looking at the full stack trace should tell you what file caused this error. – fge Mar 13 '14 at 21:26
  • @fge it's the little things in life! – John Vint Mar 13 '14 at 21:47
0

You have to traverse the entire file system and with only java (java 6) solution this is an IO bound thing. Multithreading will do little to no good. Best solution will be using the windows search api.

Query Windows Search from Java

Community
  • 1
  • 1
sumnulu
  • 3,412
  • 1
  • 19
  • 31