首页 > 解决方案 > 使用完整路径或类路径将文件作为流读取

问题描述

我有一个方法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()以使其适用于两种类型的路径?

标签: javafile

解决方案


您错误地使用了术语“类路径”。类路径是目录和/或 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)读取文件或资源。它比直接从文件中读取单个字节要快得多。

推荐阅读