复制 Jar 文件而不损坏

huangapple go评论83阅读模式
英文:

Copying Jar file without corruption

问题

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();
        
    }
}
英文:

I need to copy a .jar file (which is a resource in my project) from a separate runnable jar to the startup folder in windows. Here's the code I have so far.

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();
		
	}

}

My problem is that after the jar file is copied, it is corrupt (although the size of the original and the copy are the same.) Any thoughts on how to do this and have a runnable jar at the end of the process?

答案1

得分: 1

试试这个 -

        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();
        }
英文:

Try this -

    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();
    }

答案2

得分: 1

参考 InputStream#available方法不起作用
下面的代码行

byte[] buffer = new byte[source.available()];

是不正确的,因为 available 只返回大小的估计,当估计与实际大小不同时,JAR 文件会损坏。(来自 Java - 将 InputStream 写入文件 的示例)似乎是不正确的,因为我找不到任何保证 FileInputStreamavailable 在正确性方面的参考。

如何在Java中将 InputStream 转换为文件 的解决方案更加健壮,

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. 对于 JDK 1.7 或更高版本,Holger 建议使用 Files#copy(InputStream, Path, CopyOption...)
英文:

Refer to InputStream#available does not work.
The following line

byte[] buffer = new byte[source.available()];

is not correct, as 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) seems incorrect as I can't find any reference that guarantee correctness of available for FileInputStream.
Solution from How to convert InputStream to File in Java is more robust,

    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);

        }
    }

You can consider to use

  1. IOUtils#copy(InputStream, OutputStream)
  2. Files#copy(InputStream, Path, CopyOption...) suggested by Holger for jdk 1.7 or above

huangapple
  • 本文由 发表于 2020年10月1日 11:56:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/64148855.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定