问题描述
我需要将一个.jar文件(这是我的项目中的资源)从一个单独的可运行jar中复制到Windows中的启动文件夹中。这是我到目前为止的代码。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Installer {
public static void main(String[] args) throws IOException
{
InputStream source = Installer.class.getResourceAsstream("prank.jar");
byte[] buffer = new byte[source.available()];
source.read(buffer);
File targetFile = new File(System.getProperty("user.home") + File.separator + "AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\prank.jar");
OutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer);
outStream.close();
}
}
我的问题是,将jar文件复制后,它已损坏(尽管原始文件和副本的大小相同。)有关如何执行此操作的任何想法,并在过程结束时拥有可运行的jar ?
解决方法
尝试一下-
Path source = Paths.get("location1/abc.jar");
Path destination = Paths.get("location2/abc.jar");
try {
Files.copy(source,destination);
} catch(FileAlreadyExistsException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
,
请参阅InputStream#available does not work。 下一行
byte[] buffer = new byte[source.available()];
是不正确的,因为available
仅返回大小的 estimate ,当 estimate 与实际值不同时,jar将损坏。 (来自Java – Write an InputStream to a File的示例)似乎不正确,因为我找不到任何能够保证available
对FileInputStream
正确的引用。
How to convert InputStream to File in Java的解决方案更可靠,
private static void copyInputStreamToFile(InputStream inputStream,File file)
throws IOException {
try (FileOutputStream outputStream = new FileOutputStream(file)) {
int read;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes,read);
}
// commons-io
//IOUtils.copy(inputStream,outputStream);
}
}
您可以考虑使用
- IOUtils#copy(InputStream,OutputStream) Holger 为jdk 1.7或更高版本建议的
- Files#copy(InputStream,Path,CopyOption...)
您应该对资源使用try来关闭流,并且NIO Files.copy会为您处理InputStream:
public class Installer {
public static void main(String[] args) throws IOException {
Path targetFile = Path.of(System.getProperty("user.home"),"AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\prank.jar");
try (InputStream source = Installer.class.getResourceAsStream("prank.jar")) {
Files.copy(source,targetFile);
}
}
}