我在项目的根目录中有一个资源文件夹/程序包,我“不想”加载某个文件。如果我想加载某个文件,我将使用class.getResourceAsStream,我会很好的!我实际上想要做的是在资源文件夹中加载一个“文件夹”,循环访问该文件夹中的文件,并获取每个文件的流,然后读取内容...假定在运行时之前未确定文件名... 我该怎么办?有没有一种方法可以获取jar文件中“文件夹”中文件的列表?请注意,带有资源的Jar文件与从中运行代码的Jar文件相同。
提前致谢...
我在项目的根目录中有一个资源文件夹/程序包,我“不想”加载某个文件。如果我想加载某个文件,我将使用class.getResourceAsStream,我会很好的!我实际上想要做的是在资源文件夹中加载一个“文件夹”,循环访问该文件夹中的文件,并获取每个文件的流,然后读取内容...假定在运行时之前未确定文件名... 我该怎么办?有没有一种方法可以获取jar文件中“文件夹”中文件的列表?请注意,带有资源的Jar文件与从中运行代码的Jar文件相同。
提前致谢...
Answers:
最后,我找到了解决方案:
final String path = "sample/folder";
final File jarFile = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
if(jarFile.isFile()) { // Run with JAR file
final JarFile jar = new JarFile(jarFile);
final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
while(entries.hasMoreElements()) {
final String name = entries.nextElement().getName();
if (name.startsWith(path + "/")) { //filter according to the path
System.out.println(name);
}
}
jar.close();
} else { // Run with IDE
final URL url = Launcher.class.getResource("/" + path);
if (url != null) {
try {
final File apps = new File(url.toURI());
for (File app : apps.listFiles()) {
System.out.println(app);
}
} catch (URISyntaxException ex) {
// never happens
}
}
}
第二个块仅在IDE上运行应用程序时有效(不适用于jar文件),如果不喜欢,可以将其删除。
尝试以下方法。 例如,如果您的类路径为com.abc.package.MyClass并且
资源"<PathRelativeToThisClassFile>/<ResourceDirectory>"
文件位于src / com / abc / package / resources /中,则输入资源路径:
URL url = MyClass.class.getResource("resources/");
if (url == null) {
// error - missing folder
} else {
File dir = new File(url.toURI());
for (File nextFile : dir.listFiles()) {
// Do something with nextFile
}
}
您也可以使用
URL url = MyClass.class.getResource("/com/abc/package/resources/");
File
该类一起列出。此代码不适用于JAR文件中的资源。期。
我知道这是很多年前的事。但是,对于其他人来说,遇到这个话题。您可以做的是getResourceAsStream()
在目录路径中使用method,并且输入Stream将具有该目录中的所有文件名。之后,您可以使用每个文件名连接目录路径,并在循环中为每个文件调用getResourceAsStream。
在尝试从jar中打包的资源中加载某些hadoop配置时,我手头也遇到了同样的问题……在IDE和jar(发行版)上。
我发现java.nio.file.DirectoryStream
最好的方法是遍历本地文件系统和jar上的目录内容。
String fooFolder = "/foo/folder";
....
ClassLoader classLoader = foofClass.class.getClassLoader();
try {
uri = classLoader.getResource(fooFolder).toURI();
} catch (URISyntaxException e) {
throw new FooException(e.getMessage());
} catch (NullPointerException e){
throw new FooException(e.getMessage());
}
if(uri == null){
throw new FooException("something is wrong directory or files missing");
}
/** i want to know if i am inside the jar or working on the IDE*/
if(uri.getScheme().contains("jar")){
/** jar case */
try{
URL jar = FooClass.class.getProtectionDomain().getCodeSource().getLocation();
//jar.toString() begins with file:
//i want to trim it out...
Path jarFile = Paths.get(jar.toString().substring("file:".length()));
FileSystem fs = FileSystems.newFileSystem(jarFile, null);
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(fs.getPath(fooFolder));
for(Path p: directoryStream){
InputStream is = FooClass.class.getResourceAsStream(p.toString()) ;
performFooOverInputStream(is);
/** your logic here **/
}
}catch(IOException e) {
throw new FooException(e.getMessage());
}
}
else{
/** IDE case */
Path path = Paths.get(uri);
try {
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path);
for(Path p : directoryStream){
InputStream is = new FileInputStream(p.toFile());
performFooOverInputStream(is);
}
} catch (IOException _e) {
throw new FooException(_e.getMessage());
}
}
以下代码将所需的“文件夹”作为Path返回,而不管它是否在jar中。
private Path getFolderPath() throws URISyntaxException, IOException {
URI uri = getClass().getClassLoader().getResource("folder").toURI();
if ("jar".equals(uri.getScheme())) {
FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap(), null);
return fileSystem.getPath("path/to/folder/inside/jar");
} else {
return Paths.get(uri);
}
}
需要Java 7+。
folder
)。因此getPath
不返回folder/path/to/...
,而仅返回path/to/...
。
另一个解决方案,您可以ResourceLoader
像这样使用:
import org.springframework.core.io.Resource;
import org.apache.commons.io.FileUtils;
@Autowire
private ResourceLoader resourceLoader;
...
Resource resource = resourceLoader.getResource("classpath:/path/to/you/dir");
File file = resource.getFile();
Iterator<File> fi = FileUtils.iterateFiles(file, null, true);
while(fi.hasNext()) {
load(fi.next())
}
简单...使用OSGi。在OSGi中,您可以使用findEntries和findPaths遍历Bundle的条目。
在我的jar文件中,我有一个名为Upload的文件夹,此文件夹中还有其他三个文本文件,我需要在jar文件之外有一个完全相同的文件夹和文件,我使用下面的代码:
URL inputUrl = getClass().getResource("/upload/blabla1.txt");
File dest1 = new File("upload/blabla1.txt");
FileUtils.copyURLToFile(inputUrl, dest1);
URL inputUrl2 = getClass().getResource("/upload/blabla2.txt");
File dest2 = new File("upload/blabla2.txt");
FileUtils.copyURLToFile(inputUrl2, dest2);
URL inputUrl3 = getClass().getResource("/upload/blabla3.txt");
File dest3 = new File("upload/Bblabla3.txt");
FileUtils.copyURLToFile(inputUrl3, dest3);
正如其他答案指出的那样,一旦资源位于jar文件中,事情就会变得很丑陋。在我们的情况下,此解决方案:
https://stackoverflow.com/a/13227570/516188
在测试中效果很好(因为运行测试时,代码未打包在jar文件中),但在应用程序实际正常运行时不起作用。所以我要做的是...我在应用程序中对文件列表进行了硬编码,但是我有一个测试可以从磁盘读取实际列表(可以这样做,因为它可以在测试中工作),并且如果实际列表没有与应用返回的列表不匹配。
这样,我的应用程序中就有了简单的代码(没有技巧),并且我确定我不会忘记通过测试在列表中添加了新条目。
此链接告诉您如何。
魔术是getResourceAsStream()方法:
InputStream is =
this.getClass().getClassLoader().getResourceAsStream("yourpackage/mypackage/myfile.xml")