Дублированный файл работает иначе, чем оригинальный

У меня есть файл jar Java, завернутый в исполняемый файл. Он отлично работает при двойном щелчке.

Я попытался скопировать файл побайтно и перезаписать его в новый исполняемый файл.

Когда я пытаюсь запустить эту новую копию, я получаю сообщение об ошибке: Файл несовместим

Код, который я использовал для копирования байтов файла, выглядит следующим образом:

import java.nio.file.*;
import java.io.*;

public class Exec {

    public static void main(String args[])throws Exception {

        byte[] data = Files.readAllBytes(Paths.get("C:\\Users\\Dziugas\\Desktop\\Darts.exe"));

        File x = new File("C:\\Users\\Dziugas\\Desktop\\file.exe");

        if(!x.exists())
            x.createNewFile();

        BufferedWriter writer = new BufferedWriter(new FileWriter(x, true));

        for(byte b: data)
            writer.write(b);

        writer.close();

    }


}

Размер копии такой же, как у оригинала. Это заставляет меня задуматься об API ввода-вывода Java. Я думал, что чтение всех байтов означает именно это?

Я попытался удалить копию и снова запустить код, но ошибка осталась. Любые идеи о том, что я делаю неправильно?


person Dziugas    schedule 11.02.2015    source источник


Ответы (2)


Вы читаете файл как поток байтов, неявно приводя их к chars, а затем записывая chars. Используйте OutputStreams для записи байтов (и InputStreams для чтения байтов). Используйте Writers и Readers для записи и чтения chars.

В общем, если у вас есть массив байтов, то преобразование его в символы и обратно может полностью его исказить. Например, ваш пример может (в зависимости от платформы) привести к тому, что файл будет закодирован как UTF-8.

person user253751    schedule 11.02.2015
comment
Преобразование в char применяется ко всем потокам байтов или только к методу в классе Files? - person Dziugas; 11.02.2015
comment
@Dziugas Это не относится ни к потокам байтов, ни к Files. Это ваш код, который вызывает Writer.write(char) с byte (неявно преобразовывая байт в char). - person user253751; 11.02.2015

Вы можете попробовать так:

Path pathFrom = Paths.get("C:\\Users\\Dziugas\\Desktop\\Darts.exe");
Path pathTo = Paths.get("C:\\Users\\Dziugas\\Desktop\\file.exe");
Files.copy(pathFrom, pathTo, StandardCopyOption.COPY_ATTRIBUTES);
person ARIS    schedule 11.02.2015