Проблема с относительным пути к файлу

Итак, вот моя программа, которая работает нормально:

import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Scanner;
import java.util.Locale;

public class ScanSum {
    public static void main(String[] args) throws IOException {
        Scanner s = null;
        double sum = 0;
        try {
            s = new Scanner(new BufferedReader(new FileReader("D:/java-projects/HelloWorld/bin/usnumbers.txt")));
            s.useLocale(Locale.US);

            while (s.hasNext()) {
                if (s.hasNextDouble()) {
                    sum += s.nextDouble();
                } else {
                    s.next();
                }
            }
        } finally {
            s.close();
        }

        System.out.println(sum);
    }
}

Как вы можете видеть, я использую абсолютный путь к файлу, который я читаю:

s = new Scanner(new BufferedReader(new FileReader("D:/java-projects/HelloWorld/bin/usnumbers.txt")));

Проблема возникает, когда я пытаюсь использовать относительный путь:

s = new Scanner(new BufferedReader(new FileReader("usnumbers.txt")));

Я получаю сообщение об ошибке:

Exception in thread "main" java.lang.NullPointerException
    at ScanSum.main(ScanSum.java:24)

Файл usnumbers.txt находится в том же каталоге, что и файл ScanSum.class:

D:/java-projects/HelloWorld/bin/ScanSum.class
D:/java-projects/HelloWorld/bin/usnumbers.txt

Как я могу это решить?

Ответ 1

Из какой директории выполняется файл класса? (Это будет текущий рабочий каталог и базовый каталог для относительных путей.)

Если вы просто запустите приложение из eclipse, каталог проекта будет рабочим каталогом, и в этом случае вы должны использовать "bin/usnumbers.txt".

Ответ 2

Если предложение aioobe @не работает для вас, и вам нужно выяснить, в какой директории работает приложение, попробуйте выполнить следующие действия:

new File(".").getAbsolutePath()

Ответ 3

NullPointerException объясняется тем, что выражение new FileReader() бросает FileNotFoundException, а переменная s никогда не переопределяется ненулевым значением.

Файл "usnumbers.txt" не найден, потому что относительные пути разрешены (как и все программы) относительно текущего рабочего каталога, а не одна из многих записей в пути к классам.

Чтобы исправить первую проблему, никогда не присваивайте бессмысленное значение null, чтобы замалчивать предупреждения компилятора о неназначенных переменных. Используйте шаблон, подобный этому:

FileReader r = new FileReader(path);
try {
  Scanner s = new Scanner(new BufferedReader(r));
  ...
} finally {
  r.close();
}

Для второй проблемы смените каталоги на каталог, содержащий "usnumbers.txt" перед запуском java. Или переместите этот файл в каталог, из которого выполняется java.

Ответ 4

Это должно быть FileNotFoundException, вызывающее NPE в блоке finally. Eclipse по умолчанию выполняет класс с папкой проекта ( D:/java-projects/HelloWorld в вашем случае) в качестве рабочего каталога. Поместите файл usnumbers.txt в эту папку и попробуйте. Или измените рабочий каталог в меню "Запустить конфигурацию" → "Аргумент"

Ответ 5

Поскольку ваш рабочий каталог "D:/java-projects/HelloWorld"

@pdbartlett id отлично, но String filePath = new File(".").getAbsolutePath() выведет "D:/java-projects/HelloWorld/". что не просто добавить дополнительный относительный путь, например "filePath" + "/src/main/resources/" + FILENAME, который находится в папке ресурсов.

Я предлагаю с String filePath = new File("").getAbsolutePath(), которые возвращают корневую папку проекта

Ответ 6

В Eclipse вы также можете посмотреть в разделе "Запуск конфигураций- > Than TAB" Classpath.

По умолчанию абсолютный путь указан в разделе "Пользовательские записи" в [ значке] 'your.path' (по умолчанию classpath)