Чтение файлов из вложенной папки в банке - PullRequest
0 голосов
/ 21 ноября 2018

В моем весеннем загрузочном веб-приложении у меня есть следующая структура:

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

Я хотел бы прочитать все свойства всех файлов в папке с профилями.Решение должно работать для всего следующего:

  • Запуск из IDE
  • Запуск из банки
  • Запуск на сервере Windows
  • Работая на linux-сервере

Я столкнулся с несколькими предложениями по решению, но на самом деле не смог найти работающего.

1 Ответ

0 голосов
/ 22 ноября 2018

Основываясь на технической статье , написанной Грегом Бриггсом, я написал следующее решение:

/**
 * 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 +
                '}';
    }
}
...