Java: читатели и кодировка

На основе Вашего кода HTML в качестве примера вот один способ получить отображаемый текст в настоящее время выбираемой опции:

var skillsSelect = document.getElementById("newSkill");
var selectedText = skillsSelect.options[skillsSelect.selectedIndex].text;
11
задан jub0bs 29 February 2016 в 11:39
поделиться

5 ответов

Как Читатель узнает, что он должен использовать UTF-8?

Обычно вы указываете это сами в InputStreamReader . У него есть конструктор, принимающий кодировку символов. Например,

Reader reader = new InputStreamReader(new FileInputStream("c:/foo.txt"), "UTF-8");

Все другие считыватели (насколько мне известно) используют кодировку символов по умолчанию платформы, которая действительно может быть сама по себе неправильной кодировкой (например, -cough- CP-1252

Теоретически можно также автоматически определять кодировку символов на основе метки порядка байтов . Это отличает несколько кодировок Unicode от других кодировок. В Java SE, к сожалению, нет API для этого, но вы можете приготовить самодельный, который можно использовать для замены InputStreamReader , как в приведенном выше примере:

public class UnicodeReader extends Reader {
    private static final int BOM_SIZE = 4;
    private final InputStreamReader reader;

    /**
     * Construct UnicodeReader
     * @param in Input stream.
     * @param defaultEncoding Default encoding to be used if BOM is not found,
     * or <code>null</code> to use system default encoding.
     * @throws IOException If an I/O error occurs.
     */
    public UnicodeReader(InputStream in, String defaultEncoding) throws IOException {
        byte bom[] = new byte[BOM_SIZE];
        String encoding;
        int unread;
        PushbackInputStream pushbackStream = new PushbackInputStream(in, BOM_SIZE);
        int n = pushbackStream.read(bom, 0, bom.length);

        // Read ahead four bytes and check for BOM marks.
        if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
            encoding = "UTF-8";
            unread = n - 3;
        } else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
            encoding = "UTF-16BE";
            unread = n - 2;
        } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
            encoding = "UTF-16LE";
            unread = n - 2;
        } else if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
            encoding = "UTF-32BE";
            unread = n - 4;
        } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
            encoding = "UTF-32LE";
            unread = n - 4;
        } else {
            encoding = defaultEncoding;
            unread = n;
        }

        // Unread bytes if necessary and skip BOM marks.
        if (unread > 0) {
            pushbackStream.unread(bom, (n - unread), unread);
        } else if (unread < -1) {
            pushbackStream.unread(bom, 0, 0);
        }

        // Use given encoding.
        if (encoding == null) {
            reader = new InputStreamReader(pushbackStream);
        } else {
            reader = new InputStreamReader(pushbackStream, encoding);
        }
    }

    public String getEncoding() {
        return reader.getEncoding();
    }

    public int read(char[] cbuf, int off, int len) throws IOException {
        return reader.read(cbuf, off, len);
    }

    public void close() throws IOException {
        reader.close();
    }
}

Отредактируйте в качестве ответа на ваше редактирование :

Таким образом, кодировка зависит от ОС. Это означает, что не во всех ОС это верно:

 'a' == 97

Нет, это неправда. Кодировка ASCII (которая содержит 128 символов, 0x00 до 0x7F ) является основой всех других кодировок символов. Только символы вне кодировки ASCII могут отображаться иначе в другой кодировке. Кодировки ISO-8859 охватывают символы в диапазоне ASCII с такими же кодовыми точками. Кодировки Unicode охватывают символы из диапазона ISO-8859-1 с одинаковыми кодовыми точками.

Вы можете найти каждый из этих блогов интересным чтением:

  1. Абсолют Минимум Каждый разработчик программного обеспечения должен абсолютно точно знать о Unicode и наборах символов (никаких оправданий! ) (более теоретический из двух)
  2. Unicode - как правильно ввести символы? (более практичный из двух)
22
ответ дан 3 December 2019 в 01:16
поделиться

Кодировка Java по умолчанию зависит от вашей ОС. Для Windows это обычно «windows-1252», для Unix - «ISO-8859-1» или «UTF-8».

Читатель знает правильную кодировку, потому что вы указываете ему правильную кодировку. К сожалению, не все программы чтения позволяют это делать (например, FileReader не поддерживает), поэтому часто приходится использовать InputStreamReader .

10
ответ дан 3 December 2019 в 01:16
поделиться

Я хотел бы сначала подойти к этой части:

Кодировка Java по умолчанию - ASCII. Да?

В среде Java есть как минимум 4 различных элемента, которые можно назвать «кодировкой по умолчанию»:

  1. «кодировка по умолчанию» - это то, что Java использует для преобразования байтов в символы (и byte [ ] - Строка ) во время выполнения, когда ничего не указано. Это зависит от платформы, настроек, аргументов командной строки, ... и обычно это просто кодировка платформы по умолчанию.
  2. внутренняя кодировка символов, которую Java использует в значениях char и String объектов. Это всегда UTF-16 ! Нет возможности изменить его, это просто UTF-16! Это означает, что символ , представляющий , всегда , имеет числовое значение 97, а символ, представляющий π , всегда имеет числовое значение 960.
  3. кодировка символов, которую Java использует для хранения строковых констант в файлах .class . Это всегда UTF-8. Невозможно изменить его.
  4. кодировка, которую компилятор Java использует для интерпретации исходного кода Java в файлах .java . По умолчанию используется кодировка по умолчанию, но ее можно настроить во время компиляции.

Как Читатель узнает, что он должен использовать UTF-8?

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

Некоторые форматы, такие как XML и все XML-форматы, были разработаны с учетом этого ограничения и включают способ указания кодировки в данных, так что угадывать больше не нужно.

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

6
ответ дан 3 December 2019 в 01:16
поделиться

Для большинства читателей Java использует любую кодировку и набор символов, которые использует ваша платформа - это может быть какая-то разновидность ASCII или UTF-8, или что-то более экзотическое, например JIS (в Японии). Затем символы в этом наборе преобразуются в кодировку UTF-16, которую Java использует для внутренних целей.

Есть обходной путь, если кодировка платформы отличается от кодировки файла (моя проблема - файлы UTF-8 являются стандартными, но моя платформа использует кодировку Windows-1252). Создайте экземпляр InputStreamReader, который использует конструктор, определяющий кодировку.

Изменить: сделайте так:

InputStreamReader myReader = new InputStreamReader(new FileInputStream(myFile),"UTF-8");
//read data
myReader.close();

Однако, IIRC есть некоторые положения для автоматического определения общих кодировок (таких как UTF-8 и UTF-16). UTF-16 можно определить по метке порядка байтов в начале. UTF-8 также следует определенным правилам, но, как правило, разница между кодировкой вашей платформы и UTF-8 не имеет значения, если вы не используете международные символы вместо латинских.

5
ответ дан 3 December 2019 в 01:16
поделиться

Вы можете получить представление об этой идее здесь java Charset API

Обратите внимание, что согласно документу,

собственная кодировка символов Язык программирования Java - UTF-16

РЕДАКТИРОВАТЬ:

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

0
ответ дан 3 December 2019 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: