我需要复制一个文件夹,在运行时打包在Jar中。我想通过调用同一文件夹中包含的函数来实现。
我尝试过使用getSystemResource
:
URL sourceDirUrl = ClassLoader.getSystemResource("sourceDirName");
File sourceDir = new File(sourceDirUrl.toURI());
但它不起作用。
我可能必须递归使用getResourceAsStream
函数。是否有更优雅/更直接的方式来做到这一点?
如果我必须以递归方式执行此操作: 1.我不想指定硬编码的文件,我想动态地做 2.我不想创建单独的存档。我希望这个资源与处理它的类在同一个Jar中
由于
我最终做了Koziołek在下面提出的建议。虽然我希望有一个更优雅的解决方案,但它看起来像它一样好。
答案 0 :(得分:5)
使用类加载器无法检索文件夹,因为它不能是类路径的资源。
可能有几种解决方案:
我最好选择更便携,更灵活的第二种解决方案,但需要为文件夹内容的所有修改重新打包存档。
答案 1 :(得分:2)
Jar是简单的ZIP文件。您可以将java.util.zip。*包用于decompress个文件。
答案 2 :(得分:0)
我遇到了同样的问题,如果您浏览SO,则提出了各种解决方案,通常实施起来并不那么容易。我尝试了其中的几种,最后对我来说最好的是最简单的:
以下是执行此操作的通用方法:
/**
* Extract the contents of a .zip resource file to a destination directory.
* <p>
* Overwrite existing files.
*
* @param myClass The class used to find the zipResource.
* @param zipResource Must end with ".zip".
* @param destDir The path of the destination directory, which must exist.
* @return The list of created files in the destination directory.
*/
public static List<File> extractZipResource(Class myClass, String zipResource, Path destDir)
{
if (myClass == null || zipResource == null || !zipResource.toLowerCase().endsWith(".zip") || !Files.isDirectory(destDir))
{
throw new IllegalArgumentException("myClass=" + myClass + " zipResource=" + zipResource + " destDir=" + destDir);
}
ArrayList<File> res = new ArrayList<>();
try (InputStream is = myClass.getResourceAsStream(zipResource);
BufferedInputStream bis = new BufferedInputStream(is);
ZipInputStream zis = new ZipInputStream(bis))
{
ZipEntry entry;
byte[] buffer = new byte[2048];
while ((entry = zis.getNextEntry()) != null)
{
// Build destination file
File destFile = destDir.resolve(entry.getName()).toFile();
if (entry.isDirectory())
{
// Directory, recreate if not present
if (!destFile.exists() && !destFile.mkdirs())
{
LOGGER.warning("extractZipResource() can't create destination folder : " + destFile.getAbsolutePath());
}
continue;
}
// Plain file, copy it
try (FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length))
{
int len;
while ((len = zis.read(buffer)) > 0)
{
bos.write(buffer, 0, len);
}
}
res.add(destFile);
}
} catch (IOException ex)
{
LOGGER.log(Level.SEVERE, "extractZipResource() problem extracting resource for myClass=" + myClass + " zipResource=" + zipResource, ex);
}
return res;
}