java метод FileChannel.write() при записи в файл меняет кодировку файла

Имеется Windows 10 LTSB RU

  1. Настройки intellij idea file encoding:

       global encoding: system default: windows-1251
    
       project encoding: system default: windows-1251
    
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import static java.nio.ByteBuffer.wrap;

public class Writer {


    void writeTextToFile(String fileName) {

        String string = "Как минимум несколько вакцин от коронавируса готовы находятся в разработке и проходят испытания. " +
                "Следующим этапом, который можсобых условий " +
                "хранения — и в данном случае «особые» не значит «при температуре в диапазоне от −10 до +40 и влажности не более 80%».\n" +
                "\n" +
                "Казалось бы, вакцина готова, все самое сложное позади. Однако некоторые специалисты называют грядущий процесс «логистическим кошмаром». " +
                "Или, если не так драматизировать, чрезвычайно сложной процедурой. Почему?\n" +
                "\n" +
                "Вакцина от компании Pfizer и BioNTech должна храниться при температуре минус 70—80 градусов; от Moderna и Национальных институтов\n";
        
        try {
            string = new String(string.getBytes("windows-1251"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        
        byte[] bytesString = string.getBytes();

        try (RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
             FileChannel fc = raf.getChannel();) {
            ByteBuffer bb = wrap(bytesString, 0, bytesString.length);
            fc.write(bb);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    void insertTextToFile(String fileName) {
        
        String string = " MARKED AREA MARKED AREA MARKED AREA П р";

        try {
            string = new String(string.getBytes("windows-1251"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        byte[] b = string.getBytes();

        try (RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
             FileChannel fc = raf.getChannel();
        ) {
            ByteBuffer bb = ByteBuffer.wrap(b, 0, b.length);
            fc.write(bb);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class Program {
    private static final String FILE_NAME = "File for write insert";
    private static final String FILE_NAME2 = "File for write insert2";
    
    public static void main(String[] args){

        Writer writer=new Writer();

        writer.writeTextToFile(FILE_NAME);
        writer.insertTextToFile(FILE_NAME);
    }
}

В данном случае, если в качестве параметров задавать два разных файла то, по отдельности они будут созданы с кодировкой ANSI, если в качестве параметра указать один и тот же файл то после перезаписи методом writer.insertTextToFile() итоговый измененный файл останется в кодировке ANSI.

  1. Настройки intellij idea file encoding:

       global encoding: UTF-8
    
       project encoding: UTF-8
    
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import static java.nio.ByteBuffer.wrap;

public class Writer {


    void writeTextToFile(String fileName) {

        String string = "Как минимум несколько вакцин от коронавируса готовы к распространению, еще сотни находятся в разработке и проходят испытания. " +
                "Следующим этапом, который может оказаться весьма сложным, станет доставка препаратов. Дело в том, что предлагаемые вакцины требуют особых условий " +
                "хранения — и в данном случае «особые» не значит «при температуре в диапазоне от −10 до +40 и влажности не более 80%».\n" +
                "\n" +
                "Казалось бы, вакцина готова, все самое сложное позади. Однако некоторые специалисты называют грядущий процесс «логистическим кошмаром». " +
                "Или, если не так драматизировать, чрезвычайно сложной процедурой. Почему?\n" +
                "\n" +
                "Вакцина от компании Pfizer и BioNTech должна храниться при температуре минус 70—80 градусов; от Moderna и Национальных институтов\n";

        /*try {
            string = new String(string.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        byte[] bytesString = new byte[0];
        try {
            bytesString = string.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }*/
        
        byte[] bytesString = string.getBytes();
        try (RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
             FileChannel fc = raf.getChannel();) {
            ByteBuffer bb = wrap(bytesString, 0, bytesString.length);
            fc.write(bb);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    void insertTextToFile(String fileName) {

        String string = " MARKED AREA MARKED AREA MARKED AREA П р";

        /*try {
            string = new String(string.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        byte[] b = new byte[0];
        try {
            b = string.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }*/

        byte[] b=string.getBytes();

        try (RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
             FileChannel fc = raf.getChannel();
        ) {
            ByteBuffer bb = ByteBuffer.wrap(b, 0, b.length);
            fc.write(bb);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


public class Program {
    private static final String FILE_NAME = "File for write insert";
    private static final String FILE_NAME2 = "File for write insert2";
    
    public static void main(String[] args){

        Writer writer=new Writer();

        writer.writeTextToFile(FILE_NAME);
        writer.insertTextToFile(FILE_NAME);
    }
}

В данном же случае, если в качестве параметров задавать два разных файла то, по отдельности они будут созданы с кодировкой UTF-8, если в качестве параметра указать один и тот же файл, то после перезаписи методом writer.insertTextToFile() изначальный изменяемый файл (который был кодирован в UTF-8) перекодируется в ANSI с соответствующими последствиями(русский текст отображается некорректно). Даже если непосредственно указывать кодировку в методе string.getByte("UTF-8") ничего не меняется. Изменения в настройках intellij idea file encoding тоже ни к чему не приводят.

Вопрос: Почему так происходит? Как по итогу после изменения файла методом writer.insertTextToFile(FILE_NAME) (а точнее методом FileChannel.write()) получить измененный файл в кодировке UTF-8 не зависимо от операционной системы.


Ответы (0 шт):