【问题标题】:How to get all shell scripts inside a package如何获取包中的所有shell脚本
【发布时间】:2021-05-08 18:05:51
【问题描述】:

我使用 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")
    );

【问题讨论】:

  • 到目前为止你实现了什么?粘贴您的控制器类。如果还没有实现,请先实现。提示:制作一个简单的 hello world 控制器,向您的请求返回 hello。然后,替换容器内的代码以读取目录中的所有文件并检查文件扩展名。制作一组或列表并显示它们。您也可以使用 POJO 来表示每个文件。
  • @Ashish 再问一个问题。 “shell脚本”的名称结尾是什么。就像 java 一样,它可以是 .jar、.class。
  • @Volnick "shell script" 通常暗示着一个类 unix 的环境。类 Unix 系统并不真正关心扩展。但习惯上使用.sh
  • @FedericoklezCulloca 我编辑了我的问题。该方法适用于 java 类,但直到现在我找不到任何 shell 脚本。请查看我问题的最后一部分。

标签: java spring-boot get sh backend


【解决方案1】:

问题是您的 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;
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-23
    • 2019-09-06
    • 2016-11-13
    • 2011-09-13
    • 1970-01-01
    • 2013-08-04
    • 2013-04-27
    相关资源
    最近更新 更多