如何在包中获取所有 shell 脚本

How to get all shell scripts inside a package

我已经使用 SpringBoot 创建了一个 Java 项目,并且想要一个 Get-Request 来显示所有可用的 shell 脚本。 shell 脚本在包内:'scripts'.

import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

@RestController
@RequestMapping("api/overview")
public class DME {

String packageName = "de.osp.scriptrunnerbackend.script";

@GetMapping
public List<Class<?>> getClassesInPackage() {
    String path = packageName.replaceAll("\.", File.separator);
    List<Class<?>> classes = new ArrayList<>();
    String[] classPathEntries = System.getProperty("java.class.path").split(
            System.getProperty("path.separator")
    );

    String name;
    for (String classpathEntry : classPathEntries) {
        if (classpathEntry.endsWith(".sh")) {
            File file = new File(classpathEntry);
            try {
                JarInputStream is = new JarInputStream(new FileInputStream(file));
                JarEntry entry;
                while((entry = is.getNextJarEntry()) != null) {
                    name = entry.getName();
                    if (name.endsWith(".sh")) {
                        if (name.contains(path) && name.endsWith(".sh")) {
                            String classPath = name.substring(0, entry.getName().length() - 6);
                            classPath = classPath.replaceAll("[\|/]", ".");
                            classes.add(Class.forName(classPath));
                        }
                    }
                }
            } catch (Exception ex) {
                // Silence is gold
            }
        } else {
            try {
                File base = new File(classpathEntry + File.separatorChar + path);
                for (File file : base.listFiles()) {
                    name = file.getName();
                    if (name.endsWith(".sh")) {
                        name = name.substring(0, name.length() - 6);
                        classes.add(Class.forName(packageName + "." + name));
                    }
                }
            } catch (Exception ex) {
                // Silence is gold
            }
        }
    }

    return classes;
}

使用此方法我可以在特定包中找到 类,但它不适用于 shell 脚本。你知道 "java.class.path" 相当于 shell 脚本吗?

String[] classPathEntries = 
 System.getProperty("java.class.path").split(
            System.getProperty("path.separator")
    );

问题是您的 springboot 应用程序无法从包中查找没有 .java 扩展名的文件。您不想编译其他文件,以及来自同一包的 .java

相反,您想将 .sh 个文件和其他文件放在 src/main/resources 下。由于我们在编译时是这样把这些文件放在classpath下的,所以可以使用相对路径指定一个file/files.

我刚刚测试了此处发布的解决方案 Get a list of resources from classpath directory。下面是我的测试代码。

 Directory of ...\src\main\resources\json

05/09/2021  01:51 PM    <DIR>          .
05/09/2021  01:51 PM    <DIR>          ..
05/09/2021  01:51 PM                 2 1.json
05/09/2021  01:51 PM                 2 2.json
               2 File(s)              4 bytes
               2 Dir(s)  39,049,281,536 bytes free

显示文件列表

    @Test
    void getResourceFiles() throws IOException {
        String path = "json";
        List<String> filenames = new ArrayList<>();

        try (
                InputStream in = getResourceAsStream(path);
                BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
            String resource;

            while ((resource = br.readLine()) != null) {
                filenames.add(resource);
            }
        }
        System.out.println(filenames);
    }

    private InputStream getResourceAsStream(String resource) {
        final InputStream in
                = getContextClassLoader().getResourceAsStream(resource);

        return in == null ? getClass().getResourceAsStream(resource) : in;
    }

    private ClassLoader getContextClassLoader() {
        return Thread.currentThread().getContextClassLoader();
    }

有输出。

[1.json, 2.json]

读取一个具有完整文件名的指定文件

As soon as you have the file name, you can read it via ClassPathResource

public String getInfo() {
        String msg = "";
        InputStreamReader intput = null;
        try {
            Resource resource = new ClassPathResource("json/1.json"); // Path and file name.
            // Get the input stream. The rest would be the same as other times when you manipulate an input stream.
            intput = new InputStreamReader(resource.getInputStream());      
            BufferedReader reader = new BufferedReader(intput);
            msg=  reader.readLine();
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    return msg;
}

根据您的情况,相应地更改路径和文件名。