via*_*tic 231 java resources classpath
我正在寻找一种方法来获取给定类路径目录中的所有资源名称列表,类似于方法List<String> getResourceNames (String directoryName)
.
例如,给定一个路径目录x/y/z
包含文件a.html
,b.html
,c.html
和子目录d
,getResourceNames("x/y/z")
应该返回一个List<String>
包含下列字符串:['a.html', 'b.html', 'c.html', 'd']
.
它应该适用于文件系统和jar中的资源.
我知道我可以用File
s,JarFile
s和URL
s 写一个快速片段,但我不想重新发明轮子.我的问题是,鉴于现有的公共图书馆,实施最快捷的方式是getResourceNames
什么?Spring和Apache Commons堆栈都是可行的.
iir*_*ekm 157
实现自己的扫描仪.例如:
private List<String> getResourceFiles(String path) throws IOException {
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);
}
}
return 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();
}
Run Code Online (Sandbox Code Playgroud)
使用PathMatchingResourcePatternResolver
Spring Framework.
对于巨大的CLASSPATH值,其他技术在运行时可能会很慢.更快的解决方案是使用ronmamo的Reflections API,它在编译时预编译搜索.
Jig*_*shi 48
这是代码
来源:forums.devx.com/showthread.php?t=153784
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
/**
* list resources available from the classpath @ *
*/
public class ResourceList{
/**
* for all elements of java.class.path get a Collection of resources Pattern
* pattern = Pattern.compile(".*"); gets all resources
*
* @param pattern
* the pattern to match
* @return the resources in the order they are found
*/
public static Collection<String> getResources(
final Pattern pattern){
final ArrayList<String> retval = new ArrayList<String>();
final String classPath = System.getProperty("java.class.path", ".");
final String[] classPathElements = classPath.split(System.getProperty("path.separator"));
for(final String element : classPathElements){
retval.addAll(getResources(element, pattern));
}
return retval;
}
private static Collection<String> getResources(
final String element,
final Pattern pattern){
final ArrayList<String> retval = new ArrayList<String>();
final File file = new File(element);
if(file.isDirectory()){
retval.addAll(getResourcesFromDirectory(file, pattern));
} else{
retval.addAll(getResourcesFromJarFile(file, pattern));
}
return retval;
}
private static Collection<String> getResourcesFromJarFile(
final File file,
final Pattern pattern){
final ArrayList<String> retval = new ArrayList<String>();
ZipFile zf;
try{
zf = new ZipFile(file);
} catch(final ZipException e){
throw new Error(e);
} catch(final IOException e){
throw new Error(e);
}
final Enumeration e = zf.entries();
while(e.hasMoreElements()){
final ZipEntry ze = (ZipEntry) e.nextElement();
final String fileName = ze.getName();
final boolean accept = pattern.matcher(fileName).matches();
if(accept){
retval.add(fileName);
}
}
try{
zf.close();
} catch(final IOException e1){
throw new Error(e1);
}
return retval;
}
private static Collection<String> getResourcesFromDirectory(
final File directory,
final Pattern pattern){
final ArrayList<String> retval = new ArrayList<String>();
final File[] fileList = directory.listFiles();
for(final File file : fileList){
if(file.isDirectory()){
retval.addAll(getResourcesFromDirectory(file, pattern));
} else{
try{
final String fileName = file.getCanonicalPath();
final boolean accept = pattern.matcher(fileName).matches();
if(accept){
retval.add(fileName);
}
} catch(final IOException e){
throw new Error(e);
}
}
}
return retval;
}
/**
* list the resources that match args[0]
*
* @param args
* args[0] is the pattern to match, or list all resources if
* there are no args
*/
public static void main(final String[] args){
Pattern pattern;
if(args.length < 1){
pattern = Pattern.compile(".*");
} else{
pattern = Pattern.compile(args[0]);
}
final Collection<String> list = ResourceList.getResources(pattern);
for(final String name : list){
System.out.println(name);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Spring,请查看PathMatchingResourcePatternResolver
NS *_*oit 19
使用Google思考:
获取类路径上的所有内容:
Reflections reflections = new Reflections(null, new ResourcesScanner());
Set<String> resourceList = reflections.getResources(x -> true);
Run Code Online (Sandbox Code Playgroud)
另一个例子 - 从some.package获取扩展名为.csv的所有文件:
Reflections reflections = new Reflections("some.package", new ResourcesScanner());
Set<String> fileNames = reflections.getResources(Pattern.compile(".*\\.csv"));
Run Code Online (Sandbox Code Playgroud)
Rob*_*Rob 16
如果您使用apache commonsIO,您可以使用文件系统(可选择使用扩展名过滤器):
Collection<File> files = FileUtils.listFiles(new File("directory/"), null, false);
Run Code Online (Sandbox Code Playgroud)
和资源/类路径:
List<String> files = IOUtils.readLines(MyClass.class.getClassLoader().getResourceAsStream("directory/"), Charsets.UTF_8);
Run Code Online (Sandbox Code Playgroud)
如果你不知道文件系统或资源中是否有"directoy /",你可以添加一个
if (new File("directory/").isDirectory())
Run Code Online (Sandbox Code Playgroud)
要么
if (MyClass.class.getClassLoader().getResource("directory/") != null)
Run Code Online (Sandbox Code Playgroud)
在通话之前和两者结合使用......
小智 11
因此,就PathMatchingResourcePatternResolver而言,这是代码中所需要的:
@Autowired
ResourcePatternResolver resourceResolver;
public void getResources() {
resourceResolver.getResources("classpath:config/*.xml");
}
Run Code Online (Sandbox Code Playgroud)
列出类路径中所有资源的最健壮的机制目前是将此模式与 ClassGraph 一起使用,因为它可以处理最广泛的类路径规范机制,包括新的 JPMS 模块系统。(我是 ClassGraph 的作者。)
List<String> resourceNames;
try (ScanResult scanResult = new ClassGraph().whitelistPaths("x/y/z").scan()) {
resourceNames = scanResult.getAllResources().getNames();
}
Run Code Online (Sandbox Code Playgroud)
使用Rob的响应组合.
final String resourceDir = "resourceDirectory/";
List<String> files = IOUtils.readLines(Thread.currentThread().getClass().getClassLoader().getResourceAsStream(resourceDir), Charsets.UTF_8);
for(String f : files){
String data= IOUtils.toString(Thread.currentThread().getClass().getClassLoader().getResourceAsStream(resourceDir + f));
....process data
}
Run Code Online (Sandbox Code Playgroud)
该Spring framework
的PathMatchingResourcePatternResolver
是这些东西真的真棒:
private Resource[] getXMLResources() throws IOException
{
ClassLoader classLoader = MethodHandles.lookup().getClass().getClassLoader();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(classLoader);
return resolver.getResources("classpath:x/y/z/*.xml");
}
Run Code Online (Sandbox Code Playgroud)
Maven依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>LATEST</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
这应该有效(如果不能选择 spring):
public static List<String> getFilenamesForDirnameFromCP(String directoryName) throws URISyntaxException, UnsupportedEncodingException, IOException {
List<String> filenames = new ArrayList<>();
URL url = Thread.currentThread().getContextClassLoader().getResource(directoryName);
if (url != null) {
if (url.getProtocol().equals("file")) {
File file = Paths.get(url.toURI()).toFile();
if (file != null) {
File[] files = file.listFiles();
if (files != null) {
for (File filename : files) {
filenames.add(filename.toString());
}
}
}
} else if (url.getProtocol().equals("jar")) {
String dirname = directoryName + "/";
String path = url.getPath();
String jarPath = path.substring(5, path.indexOf("!"));
try (JarFile jar = new JarFile(URLDecoder.decode(jarPath, StandardCharsets.UTF_8.name()))) {
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.startsWith(dirname) && !dirname.equals(name)) {
URL resource = Thread.currentThread().getContextClassLoader().getResource(name);
filenames.add(resource.toString());
}
}
}
}
}
return filenames;
}
Run Code Online (Sandbox Code Playgroud)
我的方式,没有 Spring,在单元测试期间使用:
URI uri = TestClass.class.getResource("/resources").toURI();
Path myPath = Paths.get(uri);
Stream<Path> walk = Files.walk(myPath, 1);
for (Iterator<Path> it = walk.iterator(); it.hasNext(); ) {
Path filename = it.next();
System.out.println(filename);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
209870 次 |
最近记录: |