从罐子中的嵌套文件夹中读取文件

时间:2018-11-21 20:07:24

标签: spring-boot executable-jar properties-file

在我的spring-boot网络应用中,我具有以下结构:

- resources
    - properties
        - profiles
          - profile1.properties
          - profile2.properties
          - profile3.properties

我想从个人档案文件夹下的所有文件中读取所有属性。该解决方案应适用于以下所有条件:

  • 从IDE运行
  • 从罐子里跑
  • 在Windows服务器上运行
  • 在linux服务器上运行

我遇到了一些解决方案建议,但实际上找不到可行的解决方案。

1 个答案:

答案 0 :(得分:-1)

基于格雷格·布里格斯(Greg Briggs)撰写的technical article, 这是我写的解决方案:

/**
 * Loads all properties files under the given path, assuming it's under the classpath.
 *
 * @param clazz            Any class that lives in the same place as the resources you want.
 * @param parentFolderPath The profiles folder path, relative to the classpath.
 *                         Should end with "/", but not start with one.
 *                         Example: "properties/profiles/
 * @return A set of all PropertyFile that represents all the properties files under the given path
 * @throws IOException
 */
public static Set<PropertyFile> getPropertiesFromPath(Class<?> clazz, String parentFolderPath) throws IOException {
    if (!parentFolderPath.endsWith("/")) {
        throw new InvalidPathException(parentFolderPath, "Path must end with '/'");
    }
    Set<PropertyFile> retVal = Sets.newHashSet();
    URL dirURL = clazz.getClassLoader().getResource(parentFolderPath);

    if (dirURL != null && dirURL.getProtocol().equals("file")) { //IDE CASE
        Resource profilesFolderResource = new ClassPathResource(parentFolderPath);
        File profilesFolder = profilesFolderResource.getFile();
        for (File propertiesFile : profilesFolder.listFiles()) {
            Properties props = new Properties();
            try (InputStream is = FileUtils.openInputStream(propertiesFile)) {
                props.load(is);
                PropertyFile propertyFile = new PropertyFile(propertiesFile.getName(), propertiesFile.getAbsolutePath(), props);
                retVal.add(propertyFile);
            }
        }
        return retVal;
    } else if (dirURL.getProtocol().equals("jar")) { // A JAR PATH
        String jarPath = getJarPathFromURL(dirURL); //strip out only the JAR file
        JarFile jar = new JarFile(URLDecoder.decode(jarPath, Charsets.UTF_8.name()));
        Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
        while (entries.hasMoreElements()) {
            JarEntry jEntry = entries.nextElement();
            String name = jEntry.getName();
            if (isProfileFile(jEntry, parentFolderPath)) { //filter according to the path
                Path pathOfFile = Paths.get(name);
                String fileName = pathOfFile.toString().substring(pathOfFile.toString().lastIndexOf(File.separator) + 1);
                Properties props = new Properties();
                try (InputStream stream = jar.getInputStream(jEntry)) {
                    props.load(stream);
                    PropertyFile propertyFile = new PropertyFile(fileName, pathOfFile.toString(), props);
                    retVal.add(propertyFile);
                }
            }
        }
        return retVal;
    }

    throw new UnsupportedOperationException("Cannot list files for URL " + dirURL);
}

/**
 * @param jarEntry
 * @param parentFolderPath
 * @return true if the file represented by the JarEntry
 * is a properties file under the given parentFolderPath folder, else false
 */
private static boolean isProfileFile(JarEntry jarEntry, String parentFolderPath) {
    boolean result = false;
    String name = jarEntry.getName();
    if (name.endsWith(PROPERTIES_SUFFIX)) {
        Path pathOfFile = Paths.get(name);
        Path pathOfParent = Paths.get(parentFolderPath);
        String folderPath = pathOfFile.toString().substring(0, pathOfFile.toString().lastIndexOf(File.separator));
        if (folderPath.endsWith(pathOfParent.toString())) {
            result = true;
        }
    }
    return result;
}

private static String getJarPathFromURL(URL dirURL) {
    String jarPath;
    int start = OSUtil.isWindows() ? dirURL.getPath().lastIndexOf(":") - 1 : dirURL.getPath().lastIndexOf(":") + 1;
    //strip out only the JAR file
    jarPath = dirURL.getPath().substring(start, dirURL.getPath().lastIndexOf("!"));
    return jarPath;
}

public static class PropertyFile {

    public String fileName;
    public String filePath;
    public Properties properties;

    public PropertyFile(String fileName, String filePath, Properties properties) {
        this.fileName = fileName;
        this.filePath = filePath;
        this.properties = properties;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof PropertyFile)) return false;
        PropertyFile that = (PropertyFile) o;
        return Objects.equals(filePath, that.filePath);
    }

    @Override
    public int hashCode() {

        return Objects.hash(filePath);
    }

    @Override
    public String toString() {
        return "PropertyFile{" +
                "fileName='" + fileName + '\'' +
                ", filePath='" + filePath + '\'' +
                ", properties=" + properties +
                '}';
    }
}
相关问题