Java: BufferedReader продолжает записывать значения 128-159 как 63 при преобразовании в Char

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

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;

public class Why {

    public static File file = new File("why.txt");

    public static void main(String[] args) throws IOException {
        if(!file.exists())
            file.createNewFile();

        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
        bw.write((char) 144);
        bw.close();

        BufferedReader br = new BufferedReader(new FileReader(file));
        System.out.println(br.read());
        br.close();
    }
}

Любая помощь приветствуется.

Я понял это, используя FileOutputStream и FileInputStream. Спасибо всем.


person Daniel    schedule 16.06.2015    source источник
comment
Можете ли вы вставить то, что внутри файла?   -  person Rey Libutan    schedule 16.06.2015
comment
Как можно не знать, написано это или прочитано как таковое? Просто посмотрите на файл.   -  person Sami Kuhmonen    schedule 16.06.2015
comment
Почему вы приводите c к типу char? Согласно API, версия write(), которую вы используете, ожидает int.   -  person Tim Biegeleisen    schedule 16.06.2015


Ответы (2)


Когда вы используете FileReader и FileWriter, они будут использовать кодировку по умолчанию для вашей платформы. Это почти всегда плохая идея.

В вашем случае кажется, что эта кодировка не поддерживает U+0092, что вполне разумно, учитывая, что это символ личного пользования — многие кодировки не поддерживают его. Я подозреваю, что вы на самом деле вообще не хотите (char) 144. Если вы действительно хотите использовать этот символ, вам следует использовать кодировку, которая может кодировать весь Unicode — я бы рекомендовал UTF-8.

Однако важно различать текст и двоичный файл — если вас действительно интересуют только байты, то вам вообще не следует использовать программы чтения или записи — используйте InputStream и OutputStream. Шестнадцатеричные редакторы обычно ориентированы на байты, а не на текст, хотя они также могут предоставлять текстовое представление (в идеале с настраиваемой кодировкой). Если вы хотите узнать точное количество байтов в файле, вам определенно следует использовать FileInputStream.

person Jon Skeet    schedule 16.06.2015

Символ 63 — это ?, что означает, что вы используете кодировку, которая не поддерживает символ, который вы пытаетесь написать (и заменяете его на ?).

Это та часть, где вы должны ненадолго остановиться с вашим шестнадцатеричным редактором и изучить волшебный (и ужасный) мир кодировок символов и почему вы не можете их игнорировать.

Вот отличное чтение Абсолютный минимум, который каждый разработчик программного обеспечения обязательно должен знать о Unicode и наборах символов (без оправданий). !) и он по-прежнему актуален, как и в 2003 году.

person Kayaman    schedule 16.06.2015
comment
Абсолютно! Всегда указывайте набор символов, который вы хотите использовать при создании экземпляров Reader или Writer. Кодовые точки, отличные от ASCII, такие как 144, содержатся не во всех наборах символов. - person Thilo; 16.06.2015
comment
Или, что еще лучше, если это должен быть шестнадцатеричный редактор, забудьте о Reader и Writer, работайте с бинарными InputStream и OutputStream. - person Thilo; 16.06.2015
comment
Действительно, Читатель/Писатель был его первой ошибкой. - person Kayaman; 16.06.2015