如何在包中获取所有 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;
}
根据您的情况,相应地更改路径和文件名。
我已经使用 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;
}
根据您的情况,相应地更改路径和文件名。