【问题标题】:How to Properly Get a File from resources Folder如何从资源文件夹中正确获取文件
【发布时间】:2018-07-04 14:45:09
【问题描述】:

许多从资源文件夹中读取文件的教程都使用类加载器。但是,使用该方法我无法解决静态警告问题,结果始终是空指针异常。

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 在“文件”行的警告是:

ClassLoader 类型的静态方法 getSystemResource(String) 应该以静态方式访问

我无法弄清楚如何消除警告,如果我只是忽略它并运行代码,我会得到一个空指针异常。为什么我会得到这个,我该如何解决? TIA。

【问题讨论】:

  • 你在用maven吗?
  • ClassLoader.getSystemResource("test.html").getFile()
  • 感谢您的回复。我正在使用 Maven,但这有关系吗?你的建议摆脱了警告,但我仍然得到空指针异常。如果它找不到文件,无论出于何种原因,我不会得到一个找不到文件的异常吗?这是否意味着“ClassLoader.getSystemResource”有问题?
  • 为什么这是一个糟糕的问题?

标签: java resources classloader


【解决方案1】:

Test.class.getClassLoader();Class' 方法public ClassLoader getClassLoader() 获得对ClassLoader 类的引用——参见下面的private final ClassLoader classLoader

由于您是从该类的对象访问ClassLoader 类,因此您不是以静态方式访问它。

来自Class.javaJava 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 以外的方法可以解决您的问题 - 请参阅 Reading a resource file from within 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());
    }
}

【讨论】:

  • 我在给 Shantu 的评论中询问文件路径是否错误,我会得到一个未找到文件的异常,而不是空指针。假设你说路径不对,我的路径是Test->src->resources->help.html。那么文件路径会是“resources/test.html”吗?
  • 我尝试了路径“resources/test.html”,然后我得到了文件未找到异常。这非常令人困惑,因为现在我不知道空指针异常来自哪里。有趣的是如果我按照回溯中的路径,该文件确实存在。
  • @Wt Riker 我添加了更多提示:希望对您有所帮助
  • 谢谢,但不高兴。我认为底线是这个问题与目录结构和查找目标文件有关。我难住了。我试过“/test.html”、“test.html”、“resources/test.html”、“src/resources/test.html”,但它们都有同样的例外。包括赫伦的建议。
  • @Wt Riker 我测试了上面的解决方案,它在 Eclipse 和一个 jar 中工作,文件位于 srcresources 中。无论如何……祝你好运!仔细检查您的文件名:help.html 还是 test.html? ;-)
【解决方案2】:

或者您可以尝试一次全部阅读:

    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();
    }

如果您使用的是 ma​​ven,请记住根据您的情况设置 resourcesSources RootTest Sources Root)。

顺便说一句,您的解决方案可以使用Test.class.getClassLoader();

【讨论】:

    猜你喜欢
    • 2016-12-25
    • 2021-10-17
    • 2016-08-06
    • 2015-01-12
    • 2019-03-24
    • 1970-01-01
    • 2016-07-24
    • 1970-01-01
    相关资源
    最近更新 更多