Что не так с кодировками?

Версия Minecraft
1.7.10
API
Forge
210
1
19
Чтобы копировать готовый "файл настроек" (UTF-8 без BOM) из JAR-файла своего мода в папку мира, сделал такой код:
Java:
    private static boolean collectDefaultConfig(String name) {
        String path = DimensionManager.getCurrentSaveRootDirectory().getAbsolutePath() + "/RHA/" + name + ".rha";
        try {
            BufferedReader inputStream = new BufferedReader(new InputStreamReader(Main.class.getClassLoader().getResourceAsStream("assets/rha/" + name + ".rha")));
            BufferedOutputStream file = new BufferedOutputStream(new FileOutputStream(path, true));
            String line = "";
            do {
                try { line = inputStream.readLine();} catch (IOException EndOfFile){break;}
                if(line != null && line.length() > 0){file.write((line + "\n").getBytes("UTF-8"));}
            } while (line != null);
            inputStream.close();
            file.flush();
            file.close();
            System.out.println("File " + name + " grabbed from JAR successfully.");
            return true;
        } catch (Exception e) { e.printStackTrace(); return false;}
    }

Потом вывожу строку из этого файла таким образом:
Java:
    public static String getQuote(String filename, Random rnd) {
        String errorline = "Error.";
        String path = DimensionManager.getCurrentSaveRootDirectory().getAbsolutePath() + "/RHA/" + filename + ".rha";
        if(!checkConfigFileExistance(filename))return errorline + " File " + path + " isn't available.";
        try {
            List<String> alllines = new ArrayList<String>();
            BufferedReader quotefile = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"));
            String stamp = "";
            do {
                try {stamp = quotefile.readLine();} catch (IOException EndOfFile){break;}
                if(stamp == null)continue;
                if(stamp.length() < 2)continue;
                if(stamp.substring(0, 2).equalsIgnoreCase("//"))continue;
                alllines.add(stamp);
            } while (stamp != null);
            quotefile.close();
            if(alllines.size() == 0)return "List is empty.";
            if(alllines.size() == 1)return alllines.get(0);
            return alllines.get(MathHelper.getRandomIntegerInRange(rnd, 0, alllines.size() - 1));
        } catch (Exception e) {e.printStackTrace(); return errorline;}
    }

В итоге весь русский текст в конечном файле превратился в кракозябры - это видно и через блокнот и при попытке вывода содержимого файла в чат игры.

Если в первом блоке в строке:
Java:
if(line != null && line.length() > 0){file.write((line + "\n").getBytes("UTF-8"));}
убрать параметр кодировки, оставив так:
Java:
if(line != null && line.length() > 0){file.write((line + "\n").getBytes());}
то в моём файле всё становится нормально.

Если теперь убрать "UTF-8" из второго блока, то уже на этом этапе русский текст превращается в кракозябры, то есть в файле он нормальный, а в чате - хрень. Если пробовать подставлять вместо "UTF-8" слово "ISO-8859-1", то вообще не кракозябры, а знаки вопроса.

По идее проблему я решил, но очень интересно, если кто знает, объясните суть явления.
Да, и ещё остался нюанс: везде, где встречается буква "И" (заглавная), она превратилась в хрень вот так:
1637936407285.png
Я просто все фразы, где встречается эта буква, изменил так, чтобы её там не было. Но почему именно она? И почему только она?
И ещё вопрос: есть ли другой способ скопировать свой файл, кроме использованного мною? (я скопировал построчно, получается)
 
210
1
19
1637938093100.png

Первые три строки - это как должно быть. Четвертая - после того, как убрал в BufferedReader параметр UTF-8. Остальные - после того, как убрал этот параметр из getBytes.
 
210
1
19
МБ формат конца строк не тот?
Я не знаю. Весь код перед вами. Могу лишь сказать, что в плагине для 1.17 этот код работает без таких косяков. Видимо, дело в версии Java.

Попробуй получать список строк через Files.readLines(File, Charset)
Не знал о таком, сейчас попробую.
 
210
1
19
Вот такой строкой заменил 11 строк в старой версии и всё работает:
Java:
List<String> alllines = Files.readAllLines(Paths.get(path), StandardCharsets.UTF_8);

Но проблему с буквой "И" в блоке, где мы копируем файл из JAR в папку, как решить? Твоя строка работает через путь к файлу. А там у меня вот так, напомню:
Java:
BufferedReader inputStream = new BufferedReader(new InputStreamReader(Main.class.getClassLoader().getResourceAsStream("assets/rha/" + name + ".rha")));
Как будет выглядеть итоговый код?
 
112
5
16
Не знаю, у меня здесь даже такого нет - lines()
Странно, стримы появились в 8 Джаве)

Тогда могу предложить такой способ

Java:
String line;
        List<String> list = new ArrayList<>();
        while(line = inputStream.readLine() != 0){
            list.add(line);
        }
 
210
1
19
Тогда могу предложить такой способ
Так я так и делаю, вообще-то. Вот, смотри:
1637940461477.png
Красной стрелкой - то, что ты мне предлагаешь. Синими - то место, где возникает проблема. Мы берём строку из одного файла и пишем в другой. И когда мы пишем в другой - она записывается криво.

Ладно, неважно, в общем, баг старой версии это, видимо. :)
 
210
1
19
Так, что у тебя не работает конкретно сейчас?
Сейчас у меня буква "И" (русская заглавная) при копировании файла из JAR-архива в папку игры портится везде, где встречается - в каждой строчке.


IOUtils.copy в помощь. Чо вы нагородили?
Оспаде! Где ж ты раньше был?)) Всё, теперь нормально работает.
 
Сверху