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

问题描述

我已经使用 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 脚本。你知道 shell 脚本中 "java.class.path" 的等价物吗?

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

解决方法

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

相反,您希望将 .sh 文件和其他文件放在 src/main/resources 下。由于这是我们在编译期间将这些文件放在 classpath 下的方式,因此您可以使用相对路径来指定一个/多个文件。

我刚刚测试了此处发布的解决方案 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]

读取一个指定文件的全名

只要知道文件名,就可以通过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;
}

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