Как правильно получить файл из папки ресурсов - PullRequest
0 голосов
/ 04 июля 2018

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

public class Test {
    public static void main(String[] args) {
        StringBuilder contentBuilder=new StringBuilder();
        ClassLoader classLoader=Test.class.getClassLoader();
        File file=new File(classLoader.getSystemResource("test.html").getFile());
        try {
            BufferedReader buffer=new BufferedReader(new FileReader(file));
            String sCurrentLine="";
            while ((sCurrentLine=buffer.readLine())!=null) {
                contentBuilder.append(sCurrentLine);
            }
            buffer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
        String content=contentBuilder.toString();
        System.out.println("content="+content);
    }
}

Предупреждение от моей IDE в строке "Файл":

Статический метод getSystemResource (String) из типа ClassLoader должен быть доступен статическим способом

Я не могу понять, как устранить предупреждение, и если я просто игнорирую его и запускаю код, я получаю исключение нулевого указателя. Почему я получаю это и как мне это исправить? ТИА.

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Test.class.getClassLoader(); получает ссылку на класс ClassLoader из метода Class 'public ClassLoader getClassLoader() - см. private final ClassLoader classLoader ниже.

Поскольку вы обращаетесь к классу ClassLoader из объекта этого класса, вы не получаете к нему статический доступ.

С Class.java, Java SE 1.7 :

@CallerSensitive
public ClassLoader getClassLoader() {
    ClassLoader cl = getClassLoader0();
    if (cl == null)
        return null;
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
    }
    return cl;
}

// Package-private to allow ClassLoader access
ClassLoader getClassLoader0() { return classLoader; }

// Initialized in JVM not by private constructor
// This field is filtered from reflection access, i.e. getDeclaredField
// will throw NoSuchFieldException
private final ClassLoader classLoader;

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

ClassLoader.getSystemResource("test.html").getFile()

Чтобы избежать NPE, файл test.html должен находиться в вашей исходной папке.


Чтобы ответить на ваш комментарий, используйте метод, который возвращает отличное от URL решение вашей проблемы - см. Чтение файла ресурса из jar .

public class Test {

    public static void main(String[] args) {
        StringBuilder contentBuilder = new StringBuilder();

        InputStream is = Test.class.getResourceAsStream("/test.html");
        try {
            String sCurrentLine;

            BufferedReader buffer = new BufferedReader(new InputStreamReader(is));
            while ((sCurrentLine = buffer.readLine())!=null)
                contentBuilder.append(sCurrentLine);
            buffer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }

        System.out.println("content=" + contentBuilder.toString());
    }
}
0 голосов
/ 04 июля 2018

Или вы можете попробовать прочитать их все сразу:

    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    String content;
    try {
        content = new String(Files.readAllBytes(Paths.get(loader.getResource("test.html").toURI())), StandardCharsets.UTF_8);
    } catch (Exception e) {
        e.printStackTrace();
    }

Если вы используете maven , не забудьте установить ресурсов в зависимости от вашего случая (либо Sources Root, либо Test Sources Root).

Кстати, ваше решение в порядке, используя Test.class.getClassLoader();.

...