Использование файлового ввода / вывода для обхода каталога в Windows - PullRequest
4 голосов
/ 01 ноября 2011

Я пишу программу, которая использует File I / O для перемещения по каталогу, заданному пользователем, а затем добавляет каталоги в общий связанный список.Написанная мною программа прекрасно работает в Ubuntu, но не работает, когда я пытаюсь использовать ее в Windows.Это довольно длинная программа, но я думаю, что эта часть имеет проблемы:

private Node<Item> currentNode = new Node<Item>();

public void traverse(File fileObject)
{
    File allFiles[] = fileObject.listFiles();

    for(File aFile: allFiles){
        System.out.println(aFile.getName()); /* debugging */
        recursiveTraversal(aFile); /* Line 34 */
    }
}


public void recursiveTraversal(File fileObject){
    Node<Item> newNode = new Node<Item>();
    currentNode.addChild(newNode);
    currentNode = newNode;
    if (fileObject.isDirectory()){
        newNode.setData(new Item());

        File allFiles[] = fileObject.listFiles();
        for(File aFile : allFiles){ /* This is line 48 */
            recursiveTraversal(aFile);
        }            

    }else if (fileObject.isFile()){
        newNode.setData(new Item());
    }           
    currentNode = newNode.getParent();
}

Когда я использую ее в Linux, я могу дать ей что-то вроде /home/matt/Documents, и она работает, но когда я пытаюсьWindows, используя G:\\Users\\Matt\\Documents это ошибки.Оператор print, который я добавил, на самом деле распечатывает файлы в папке, но что-то с остальной частью программы не работает:

java.lang.NullPointerException
at FileTraverse.recursiveTraversal(FileTraverse.java:48)
at FileTraverse.traverse(FileTraverse.java:34)
at DirectoryMain$ClickAction.actionPerformed(DirectoryMain.java:103)
    ...

После этого возникает множество ошибок, связанных с Swing GUI этой программы.уходит, но я не думаю, что это связано с чем-либо.

РЕДАКТИРОВАТЬ: Добавлено в номера строк, которые соответствуют трассе.

Ответы [ 5 ]

3 голосов
/ 01 ноября 2011

Из Javadoc из File.listFile () (выделение добавлено):

Возвращает: Массив абстрактных путей, обозначающих файлы и каталоги в каталоге, обозначенном этимабстрактный путьМассив будет пустым, если каталог пуст. Возвращает ноль, если это абстрактное имя пути не обозначает каталог или если произошла ошибка ввода-вывода.

Вам нужно будет справиться с нулевыми возвращениями из listFiles(),К сожалению, с помощью java.io.File API невозможно точно определить, какая именно ошибка произошла.

Если вы используете Java 7, вы можете использовать класс DirectoryStream :

private void recursiveTraversal(Path path)
throws IOException
{
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) 
    {
        for (Path entry : stream) 
        {
            //Do something with entry
            doSomething(entry);

            if (Files.isDirectory(entry))
                recursiveTraversal(entry);
        }
    }
}

Разница в том, что newDirectoryStream() может выдать IOException (или подкласс, такой как AccessDeniedException, который дает информацию о причине сбоя вызова.

1 голос
/ 01 ноября 2011

я предполагаю, что вы попали в каталог, который по какой-то причине окна не позволяют вам просматривать. listFiles (), скорее всего, возвращает ноль в этом случае.

1 голос
/ 01 ноября 2011

Если вы получили NullPointerException в строке 48, это должно означать, что полученный массив allFiles равен null.В соответствии с JavaDoc для этого метода это должно происходить только в том случае, если файл, к которому вы его вызываете, не является каталогом или произошла ошибка ввода-вывода.Это немного странно, так как вы проверяете, является ли это каталогом в if.Возможно, на уровне ОС существует проблема с правами доступа.

Возможно, вы захотите использовать FileFilter s или что-то из пакета java.nio.file.Я полагаю, что последнее облегчает прохождение каталогов.

0 голосов
/ 17 января 2014

Я пробовал что-то похожее в Windows, и программа вылетала и возвращала исключение nullPointerException, как только программа пыталась перейти в каталог, к которому разрешения безопасности имели ограниченный доступ.

Если вам не нужна программа для добавления защищенных / скрытых / системных папок, просто обработайте ошибку, используя предложение try catch.

public static void dive(File file, int level){    
    try{
        for(File x : file.listFiles())
            if(x.isDirectory() && !x.isHidden())
                dive(x);
     }catch(NullPointerException e){
        // Do nothing..
     }
 }

Это должно пройти через все пользовательские каталоги

0 голосов
/ 01 ноября 2011

Разница между traverse() и recursiveTraversal() немного странно для меня; когда бы вы использовали traverse()? Какую роль это играет что recursiveTraversal() еще не сделал? Конечно, traverse() предполагает он работает с каталогом, но recursiveTraversal() уже обрабатывает каталоги хорошо.

Там все возится с Item s в recursiveTraversal(), но поскольку они не ничего не делают здесь, трудно найти утилиту. :)

public void traverse(File fileObject)
{
    File allFiles[] = fileObject.listFiles();

    for(File aFile: allFiles){
        System.out.println(aFile.getName()); /* debugging */
        recursiveTraversal(aFile);
    }
}


public void recursiveTraversal(File fileObject){
    Node<Item> newNode = new Node<Item>();
    currentNode.addChild(newNode);
    currentNode = newNode;
    if (fileObject.isDirectory()){
        newNode.setData(new Item());

        File allFiles[] = fileObject.listFiles();
        for(File aFile : allFiles){
            recursiveTraversal(aFile);
        }            

    }else if (fileObject.isFile()){
        newNode.setData(new Item());
    }           
    currentNode = newNode.getParent();
}

Я бы, вероятно, переместил newNode.setData(new Item()); выше isDirectory() отметьте, чтобы у newNode был новый Item добавляется к нему независимо от того, является ли текущий fileObject файлом или каталогом:

public void recursiveTraversal(File fileObject){
    Node<Item> newNode = new Node<Item>();
    currentNode.addChild(newNode);
    currentNode = newNode;
    newNode.setData(new Item());
    if (fileObject.isDirectory()){
        File allFiles[] = fileObject.listFiles();
        for(File aFile : allFiles){
            recursiveTraversal(aFile);
        }            
    }else if (fileObject.isFile()){
        /* must do _something_ with files */
    }           
    currentNode = newNode.getParent();
}
...