从 jar 文件复制目录
我最近开发了一个应用程序并创建了 jar 文件。
我的一个类创建一个输出目录,用其资源中的文件填充它。
我的代码是这样的:
// Copy files from dir "template" in this class resource to output.
private void createOutput(File output) throws IOException {
File template = new File(FileHelper.URL2Path(getClass().getResource("template")));
FileHelper.copyDirectory(template, output);
}
不幸的是,这不起作用。
我尝试了以下方法,但没有成功:
使用 Streams 解决类似的问题 在其他课程上但不起作用 与目录。代码类似于 http://www.exampledepot.com/egs/java.io/CopyFile.html
使用
new File(getClass().getResource("template").toUri()) 创建文件模板
在编写本文时,我正在考虑不要在资源路径中包含一个带有 zip 文件的模板目录。通过这种方式,我可以将文件作为 inputStream 获取,并将其解压缩到我需要的位置。但我不确定这是否是正确的方法。
I have recently developed an application and created the jar file.
One of my classes creates an output directory, populating it with files from its resource.
My code is something like this:
// Copy files from dir "template" in this class resource to output.
private void createOutput(File output) throws IOException {
File template = new File(FileHelper.URL2Path(getClass().getResource("template")));
FileHelper.copyDirectory(template, output);
}
Unfortunately this doesn't work.
I tried the following without luck:
Using Streams to solve similar stuff
on other classes but it doesn't work
with dirs. Code was similar to
http://www.exampledepot.com/egs/java.io/CopyFile.htmlCreating the File template with
new File(getClass().getResource("template").toUri())
While writing this I was thinking about instead of having a template dir in the resource path having a zip file of it. Doing it this way I could get the file as an inputStream and unzip it where I need to. But I am not sure if it's the correct way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
感谢您的解决方案!对于其他人,以下不使用辅助类(StringUtils 除外)
/我为此解决方案添加了额外信息,请检查代码末尾,Zegor V/
它只使用 Apache Software Foundation 的一个外部库,但是所使用的功能仅:
我的知识仅限于 Apache 许可证,但您可以在没有库的情况下在代码中使用此方法。但是,如果有许可证问题,我不承担任何责任。
Thanks for the solution! For others, the following doesn't make use of the auxiliary classes (except for StringUtils)
/I added extra information for this solution, check the end of the code, Zegor V/
It uses only one external library from the Apache Software Foundation, however the used functions are only :
My knowledge is limited on Apache licence, but you can use this methods in your code without library. However, i am not responsible for licence issues, if there is.
使用 Java7+ 可以通过创建
FileSystem
然后使用walkFileTree
递归复制文件来实现。该方法可以这样使用:
Using Java7+ this can be achieved by creating
FileSystem
and then usingwalkFileTree
to copy files recursively.The method can be used like this:
我认为您使用 zip 文件的方法是有意义的。大概您将执行 getResourceAsStream 来获取 zip 的内部结构,它在逻辑上看起来像目录树。
骨架方法:
I think your approach of using a zip file makes sense. Presumably you'll do a
getResourceAsStream
to get at the internals of the zip, which will logically look like a directory tree.A skeleton approach:
我讨厌使用之前发布的 ZIP 文件方法的想法,所以我想出了以下方法。
示例用法(将所有文件从类路径资源“config”复制到“${homeDirectory}/config”:
这对于从平面文件和 Jar 文件进行复制都应该有效。
注意:上面的代码使用了一些自定义实用程序类( FileUtils、CollectionUtils)以及一些来自 Apache commons-lang (StringUtils) 的函数,但这些函数的命名应该相当明显。
I hated the idea of using the ZIP file method posted earlier, so I came up with the following.
Example Useage (copies all files from the classpath resource "config" to "${homeDirectory}/config":
This should work both for copying from both flat files as well as Jar files.
Note: The code above uses some custom utility classes (FileUtils, CollectionUtils) as well as some from Apache commons-lang (StringUtils), but the functions should be named fairly obviously.
lpiepiora的答案是正确的!但有一个小问题,
源,应该是一个jar URL。当源路径是文件系统的路径时,上述代码将无法正常工作。
要解决这个问题,应该使用ReferencePath,代码可以从以下链接获取:
通过 FileSystem 对象从文件系统读取
copyFromJar 的新代码应如下所示:
The answer of lpiepiora, is correct! But there is a minor issue,
The source, should be a jar Url. When the source path is path to a file system, then the above code will not work proper.
To solve this problem, you should use the ReferencePath, the code, you can get from the following link:
Read from file system via FileSystem object
The new code of copyFromJar should like:
我不确定 FileHelper 是什么或做什么,但您将无法直接从 JAR 复制文件(或目录)。正如您所提到的,使用 InputStream 是正确的方法(来自 jar 或 zip):
您需要对每个文件执行上述操作(当然,适当地处理异常)。您可能能够也可能无法(取决于您的部署配置)将有问题的 jar 文件读取为 JarFile(例如,如果部署为非扩展 Web 应用程序的一部分,则它可能无法作为实际文件使用)。如果您能阅读它,您应该能够迭代 JarEntry 实例列表,从而重建您的目录结构;否则您可能需要将其存储在其他地方(例如,在文本或 xml 资源中)
您可能需要查看 Commons IO 库 - 它提供了许多常用的流/文件功能,包括复制。
I'm not sure what
FileHelper
is or does, but you will NOT be able to copy files (or directories) directly from JAR. Using InputStream as you've mentioned is the correct way (from either jar or zip):You'll need to do the above (handling exceptions appropriately, of course) for each of your files. You may or may not be able (depending on your deployment configuration) to read jar file in question as JarFile (it may not be available as an actual file if deployed as part of non-expanded web app, for example). If you can read it, you should be able to iterate through list of JarEntry instances and thus reconstitute your directory structure; otherwise you may need to store it elsewhere (within text or xml resource, for example)
You may want to take a look at Commons IO library - it provides a lot of commonly used stream / file functionality including copying.
这是来自 tess4j 项目:
Here is a working version from the tess4j project:
我知道这个问题现在有点老了,但是在尝试了一些不起作用的答案以及其他仅需要整个库才能实现一种方法的答案之后,我决定组建一个课程。它不需要第三方库,并且已经使用 Java 8 进行了测试。有四个公共方法:
copyResourcesToTempDir
、copyResourcesToDir
、copyResourceDirectory
和jar
。I know this question is kind of old now but after trying some answers that didn't work and others that required a whole library for just one method, I decided to put together a class. It doesn't require third-party libraries and it's been tested with Java 8. There are four public methods:
copyResourcesToTempDir
,copyResourcesToDir
,copyResourceDirectory
andjar
.您可以使用 ClassLoader 来获取 流式传输到资源。获得输入流后,您可以读取该流的内容并将其写入输出流。
在您的情况下,您需要创建多个 OutputStream 实例,每个实例对应一个要复制到目标的文件。当然,这需要您事先知道文件名。
对于此任务,最好使用 getResourceAsStream,而不是 getResource 或 getResources()。
You could use the ClassLoader to obtain a stream to the resource. Once you have obtained an InputStream, you can read off, and write the contents of the stream, onto an OutputStream.
In your case, you'll need to create several OutputStream instances, one for each file that you want to copy over to the destination. This of course, requires that you know of the file names before hand.
For this task, it is preferred to use getResourceAsStream, rather than getResource or getResources().
我最近也遇到了类似的问题。我尝试从 java 资源中提取文件夹。所以我用 Spring PathMatchingResourcePatternResolver 解决了这个问题。
此代码从指定资源获取所有文件和目录:
这是将所有文件和目录从资源复制到磁盘路径的类。
}
I have faced the similair problem recently. I tried to extract folder from java resources. So I resolved this issue with Spring PathMatchingResourcePatternResolver.
This code gets all files and directories from the specified resource:
And this is the class that copy all files and directories from the resource to the disk path.
}
我喜欢 @nivekastoreth (https://stackoverflow.com/a/2993908/13768174) 的回复,但无法直接使用它,因为它依赖于第三方库。
我只是重写它以使用 java.nio.file.Files
假设我想复制这样的文件夹:
我可以像这样调用方法:
这是实现:
I liked the response from @nivekastoreth (https://stackoverflow.com/a/2993908/13768174) but was not able to use it directly because it was relying on third party libraries.
I just rewrote it to use
java.nio.file.Files
Let's say I want to copy a folder like this:
I can just call the method like this:
Here is the implementation:
它可以非常容易地使用(apache commons-io)依赖项
相关的maven依赖项:
It can very easy using (apache commons-io) dependency
Related maven dependency:
您可以使用我的图书馆:
编译组:'com.github.ardenliu',名称:'arden-file',版本:'0.0.4'ResourcesUtils
类:
copyFromClassPath(最终字符串资源路径,最终路径targetRoot)
源代码:
https://github.com/ardenliu/common/blob/master/arden-file/src/main/java/com/github/ardenliu/common/file/ResourcesUtils.java
Junit 测试:
Eclipse 类路径的一个测试用例;另一个用于罐子
https://github.com/ardenliu/common/blob/master/arden-file/src/test/java/com/github/ardenliu/common/file/ResourcesUtilsTest.java
You can use my library:
compile group: 'com.github.ardenliu', name: 'arden-file', version: '0.0.4'
ResourcesUtils class:
copyFromClassPath(final String resourcePath, final Path targetRoot)
Source Code:
https://github.com/ardenliu/common/blob/master/arden-file/src/main/java/com/github/ardenliu/common/file/ResourcesUtils.java
Junit testing:
One testing case for Eclipse classpath; another one for jar
https://github.com/ardenliu/common/blob/master/arden-file/src/test/java/com/github/ardenliu/common/file/ResourcesUtilsTest.java