![](/img/trans.png)
[英]How to access the excels sheets while running the Jar file inside it and copy outside jar?
[英]How to copy file inside jar to outside the jar?
我想从jar中复制一个文件。 我要复制的文件将被复制到工作目录之外。 我做了一些测试,我尝试的所有方法都以0字节文件结束。
编辑 :我希望通过程序复制文件,而不是手动。
首先,我想说之前发布的一些答案是完全正确的,但我想给我的,因为有时我们不能在GPL下使用开源库,或者因为我们懒得下载jar XD或者什么你的理由是一个独立的解决方案。
下面的函数复制Jar文件旁边的资源:
/**
* Export a resource embedded into a Jar file to the local file path.
*
* @param resourceName ie.: "/SmartLibrary.dll"
* @return The path to the exported resource
* @throws Exception
*/
static public String ExportResource(String resourceName) throws Exception {
InputStream stream = null;
OutputStream resStreamOut = null;
String jarFolder;
try {
stream = ExecutingClass.class.getResourceAsStream(resourceName);//note that each / is a directory down in the "jar tree" been the jar the root of the tree
if(stream == null) {
throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file.");
}
int readBytes;
byte[] buffer = new byte[4096];
jarFolder = new File(ExecutingClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile().getPath().replace('\\', '/');
resStreamOut = new FileOutputStream(jarFolder + resourceName);
while ((readBytes = stream.read(buffer)) > 0) {
resStreamOut.write(buffer, 0, readBytes);
}
} catch (Exception ex) {
throw ex;
} finally {
stream.close();
resStreamOut.close();
}
return jarFolder + resourceName;
}
只需将ExecutingClass更改为您的类的名称,并将其命名为:
String fullPath = ExportResource("/myresource.ext");
正如GOXR3PLUS所回答并由安迪·托马斯注意到的,您可以通过以下方式实现此目的:
Files.copy( InputStream in, Path target, CopyOption... options)
有关详细信息,请参阅GOXR3PLUS答案
鉴于您对0字节文件的评论,我不得不假设您正在尝试以编程方式执行此操作,并且,鉴于您的标记,您正在使用Java进行此操作。 如果这是真的,那么只需使用Class.getResource()来获取指向JAR中文件的URL,然后使用Apache Commons IO FileUtils.copyURLToFile()将其复制到文件系统。 例如:
URL inputUrl = getClass().getResource("/absolute/path/of/source/in/jar/file");
File dest = new File("/path/to/destination/file");
FileUtils.copyURLToFile(inputUrl, dest);
最有可能的是,您现在拥有的任何代码的问题是您(正确地)使用缓冲输出流来写入文件但是(错误地)无法关闭它。
哦,你应该修改你的问题澄清你到底如何想这样做(编程,不是语言,...)
Java 8(实际上是自1.7以来的FileSystem)附带了一些很酷的新类/方法来处理这个问题。 有人已经提到JAR基本上是ZIP文件,你可以使用
final URI jarFileUril = URI.create("jar:file:" + file.toURI().getPath());
final FileSystem fs = FileSystems.newFileSystem(jarFileUri, env);
(见Zip文件 )
然后你可以使用一种方便的方法,如:
fs.getPath("filename");
然后你可以使用Files类
try (final Stream<Path> sources = Files.walk(from)) {
sources.forEach(src -> {
final Path dest = to.resolve(from.relativize(src).toString());
try {
if (Files.isDirectory(from)) {
if (Files.notExists(to)) {
log.trace("Creating directory {}", to);
Files.createDirectories(to);
}
} else {
log.trace("Extracting file {} to {}", from, to);
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException e) {
throw new RuntimeException("Failed to unzip file.", e);
}
});
}
注意:我尝试解压缩JAR文件以进行测试
使用Java 7+更快的方式,以及获取当前目录的代码:
/**
* Copy a file from source to destination.
*
* @param source
* the source
* @param destination
* the destination
* @return True if succeeded , False if not
*/
public static boolean copy(InputStream source , String destination) {
boolean succeess = true;
System.out.println("Copying ->" + source + "\n\tto ->" + destination);
try {
Files.copy(source, Paths.get(destination), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
logger.log(Level.WARNING, "", ex);
succeess = false;
}
return succeess;
}
测试它( icon.png是应用程序包图像中的图像):
copy(getClass().getResourceAsStream("/image/icon.png"),getBasePathForClass(Main.class)+"icon.png");
关于代码行( getBasePathForClass(Main.class)
): - >检查我在这里添加的答案:) - > 用Java获取当前工作目录
使用JarInputStream类:
// assuming you already have an InputStream to the jar file..
JarInputStream jis = new JarInputStream( is );
// get the first entry
JarEntry entry = jis.getNextEntry();
// we will loop through all the entries in the jar file
while ( entry != null ) {
// test the entry.getName() against whatever you are looking for, etc
if ( matches ) {
// read from the JarInputStream until the read method returns -1
// ...
// do what ever you want with the read output
// ...
// if you only care about one file, break here
}
// get the next entry
entry = jis.getNextEntry();
}
jis.close();
另请参见: JarEntry
强大的解决方案:
public static void copyResource(String res, String dest, Class c) throws IOException {
InputStream src = c.getResourceAsStream(res);
Files.copy(src, Paths.get(dest), StandardCopyOption.REPLACE_EXISTING);
}
你可以像这样使用它:
File tempFileGdalZip = File.createTempFile("temp_gdal", ".zip");
copyResource("/gdal.zip", tempFileGdalZip.getAbsolutePath(), this.getClass());
要将文件从jar复制到外部,需要使用以下方法:
getResourceAsStream()
获取一个InputStream
到jar文件中的文件 FileOutputStream
打开目标文件 示例代码,其中还包含一个不替换现有值的变量:
public File saveResource(String name) throws IOException {
return saveResource(name, true);
}
public File saveResource(String name, boolean replace) throws IOException {
return saveResource(new File("."), name, replace)
}
public File saveResource(File outputDirectory, String name) throws IOException {
return saveResource(outputDirectory, name, true);
}
public File saveResource(File outputDirectory, String name, boolean replace)
throws IOException {
File out = new File(outputDirectory, name);
if (!replace && out.exists())
return out;
// Step 1:
InputStream resource = this.getClass().getResourceAsStream(name);
if (resource == null)
throw new FileNotFoundException(name + " (resource not found)");
// Step 2 and automatic step 4
try(InputStream in = resource;
OutputStream writer = new BufferedOutputStream(
new FileOutputStream(out))) {
// Step 3
byte[] buffer = new byte[1024 * 4];
int length;
while((length = in.read(buffer)) >= 0) {
writer.write(buffer, 0, length);
}
}
return out;
}
jar只是一个zip文件。 解压缩(使用您熟悉的任何方法)并正常复制文件。
${JAVA_HOME}/bin/jar -cvf /path/to.jar
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.