使用完整路径或类路径将文件读取为流

时间:2019-03-27 03:22:22

标签: java file

我有一个方法getMyFilePath(),可以将路径返回为目录String

它可以返回类路径:\com\mypackage\configdir\ 要么 它可以返回完整路径:C:\configdir\

我想修改以下代码,以便它可以处理以上两种情况:

public void myMethod() {
   String myConfigDirPath = getMyFilePath();
   File configFile = new File(myConfigDirPath + "myConfig.txt");
   try (InputStream is = new FileInputStream(configFile)) {
     // do something
   } catch (IOException e) {
      e.printStackTrace();
   }
}

myMethod()在路径已满即C:\configdir\时运行良好,但在路径为类路径即InputStream时在\com\mypackage\configdir\行给出了以下错误:

java.io.FileNotFoundException: \com\mypackage\configdir\myConfig.txt 
(The system cannot find the path specified)

如何修改myMethod()使其适用于两种类型的路径?

2 个答案:

答案 0 :(得分:0)

如果文件位于类路径中,则可以使用以下方法从类路径中加载文件:

      ClassLoader classLoader = <YourClass>.class.getClassLoader();
      InputStream is = classLoader.getResourceAsStream("myConfig.txt");

您可以将其放在Catch块中,或者可以先检查它是否是类路径,然后适当调用

答案 1 :(得分:0)

您错误地使用了“类路径”一词。类路径是目录和/或jar文件的列表,用于在运行时或编译时解析类和资源。

\com\mypackage\configdir\myConfig.txt的恰当术语是一个资源。它可能在源代码树中时是一个文件,但是如果您尝试将程序打包为jar文件,它将将位于jar归档文件中,并且根本不会是文件,因此您无法使用FileInputStream读取它。

使用getResourceAsStream方法读取资源,该方法专门用于检索与应用程序捆绑在一起的静态数据:

File configFile = new File(myConfigDirPath + "myConfig.txt");
try (InputStream is = new BufferedInputStream(
    configFile.exists()
        ? new FileInputStream(configFile)
        : MyApplication.class.getResourceAsStream(
            configFile.toString().replace('\\', '/')))) {

    // do something
}

可以通过将配置读取逻辑移至单独的私有方法来使其更加清晰:

File configFile = new File(myConfigDirPath + "myConfig.txt");
if (configFile.exists()) {
    try (InputStream is = new BufferedInputStream(
        new FileInputStream(configFile))) {

        readConfigurationFrom(is);
    }
} else {
    String configResourcePath =
        configFile.toString().replace('\\', '/')))) {
    InputStream configResource =
        MyApplication.class.getResourceAsStream(configResourcePath);

    if (configResource == null) {
        throw new ConfigurationException(
            "Cannot find the file \"" + configFile + "\""
            + " or the resource \"" + configResourcePath + "\"");
    }

    try (InputStream is = new BufferedInputStream(configResource)) {
        readConfigurationFrom(is);
    }
}

一些附加说明:

  • 将资源指定为相对URL,例如/com/mypackage/configdir/myConfig.txt。在所有平台上,URL 始终始终使用正斜杠(/)。
  • 您应该始终使用BufferedInputStream(或BufferedReader)读取文件或资源。这比直接从文件中读取单个字节要快得多。