复制 Jar 文件而不损坏

Copying Jar file without corruption

我需要将一个 .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 only return estimate of the size, the jar will be corrupted when estimate is different with actual. (Example from Java – Write an InputStream to a File) 似乎不正确,因为我找不到任何保证 FileInputStream.
available 正确性的参考资料 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, 0, read);
            }

            // commons-io
            //IOUtils.copy(inputStream, outputStream);

        }
    }

可以考虑使用

  1. IOUtils#copy(InputStream, OutputStream)
  2. Files#copy(InputStream, Path, CopyOption...) Holger 建议 jdk 1.7 或更高版本