Java: запись / чтение символа в файл дает разные результаты - PullRequest
0 голосов
/ 09 ноября 2011

Я пытаюсь записать простой символ в файл и прочитать его обратно. Запись символа в файл работает нормально (по крайней мере, так, как это выглядит в шестнадцатеричном редакторе). Когда я читаю персонажа обратно в память, это совершенно другое значение. Вот мой пример кода:

public class myclass {

public static void main(String[] args) {
      char myChar = 158; // let myChar = 158

      System.out.println("myChar = "+(int)myChar); // prints 158. Good.   

        try {
            FileOutputStream fileOut = new FileOutputStream("readthis");
                fileOut.write(myChar);
            fileOut.close();
        } catch (IOException e) {
            System.exit(1);
        }


        // If I examine the "readthis" file, there is one byte that has a value of
        // of '9E' or 158. This is what I'd expect.   

        // Lets try to now read it back into memory   


        char readChar = 0;

        try {
            int i = 0;

            FileInputStream fstream = new FileInputStream("readthis");
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));

                readChar = (char)br.read();                     


            in.close();

        } catch (IOException e) {
            System.exit(1);
        }

        // Now, if we look at readChar, it's some value that's not 158!
        // Somehow it got read into as 382!   

        // Printing this value results in 382
        System.out.println("readChar = "+(int)readChar);




  }

}

Мой вопрос: как это случилось? Я бы хотел, чтобы readChar равнялся исходному значению, которое я написал (158), но я не уверен, что я делаю неправильно. Любая помощь будет оценена. Спасибо.

Ответы [ 3 ]

5 голосов
/ 09 ноября 2011

Вы пишете байты и читаете символы. Используйте Writer и Reader или OutputStream и InputStream.

3 голосов
/ 09 ноября 2011

EJP прав. Более подробное объяснение: у персонажа есть два свойства, а вы пропускаете одно: Кодировка.

Это означает, что char myChar = 158 назначает myChar кодовую точку Unicode 158 (это не печатный символ в Unicode).

Когда вы записываете это в файл в виде байта (используя fileOut.write(int)), вы конвертируете символ Unicode в целое число 158 - кодировка теряется. Метод write() удаляет из целого числа все, кроме младших 8 бит (write(158+256) дает тот же результат, что и write(158)).

Когда вы снова читаете данные, вы используете Reader, который читает байты и преобразует их в символы Юникода. Чтобы сделать это правильно, вам нужно указать кодировку, с которой были записаны данные. Поскольку вы ничего не указали явно, Java использует кодировку платформы по умолчанию (по умолчанию для вашей ОС).

Таким образом, читатель читает 158 и использует кодировку по умолчанию, чтобы превратить это в char.

Чтобы исправить это, всегда используйте Reader / Writer вместе с InputStreamReader и OutputStreamWriter, которые позволяют вам указать, какую кодировку использовать. UTF-8 - хороший выбор, поскольку все виртуальные машины Java могут их читать, а все символы Unicode можно переводить в / из этой кодировки.

1 голос
/ 09 ноября 2011

Если вы хотите только писать / читать символы, попробуйте DataOutputStream#writeChar() и DataInputStream#readChar(), но InputStreamRead / OutputStreamWriter более гибкие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...