Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > ISO-8859-Х кодировка


Автор: Kizja 8.5.2008, 19:11
Привет, чего-то не могу понять, как получить числовые значения байтов в ISO-8859-5, пробую так:

Код

    public static void main(String[] args) throws IOException {
        byte[] bytes = "Абракадабра".getBytes("8859_5");

        Writer out = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream("output.txt"),"8859_5"));

        out.write(new String(bytes, "8859_5"));
        writeBytes(out, bytes);
        out.close();
    }
    
    private static void writeBytes(Writer out, byte[] bytes) throws IOException {
        out.write("\nБайты: ");
        for (int i = 0; i < bytes.length; i++) {
            out.write(bytes[i] + " ");
        }
        out.write("\nСимволы: ");
        for (int i = 0; i < bytes.length; i++) {
            out.write((char) bytes[i] + " ");
        }
    }


В итоге в файл сохраняются следующие данные:

Абракадабра
Байты: -80 -47 -32 -48 -38 -48 -44 -48 -47 -32 -48 
Символы: ? ? ? ? ? ? ? ? ? ? ? 

Первая строчка с текстом показывается как надо, в строке "Байты" выводит неверные числа судя по вот этой таблице: http://www.sbnet.ru/soft/fluids/charsets/iso.htm , где например буква "А"
 в слове "Абракадабра" соотвествует этому: "0xB0    0x0410    #    CYRILLIC CAPITAL LETTER A", т.е. "0xB0" => если я не ошибаюсь равняется 176, а он выводит -80. Вместо символов тоже выводит вопросы, кто-нибудь знает как эти данные получить по человечески ?

Автор: LSD 11.5.2008, 17:01
byte в Java знаковый тип, так что выводить его надо приблизительно так:
Код

System.out.printf("%02X ", 0xFF & b);


Насчет того, что в строке символы выводится абракадабра - ты уверен, что кодикорвка 8859_5 поддерживает те символы, что ты хочешь вывести?

Автор: Kizja 12.5.2008, 00:30
LSD, возник переделанный вариант, где символы тоже выводит, но всё равно есть проблема:

Код

public class TestEncoding {
    private static final String ISO_5 = "ISO-8859-5";
    private static final String TEST_FILE = "output.txt";
    private static final String TEST_MESSAGE = "Ю";
    
    public static void main(String[] args) throws IOException {
        CharBuffer cbuf = getCharBuffer(ISO_5, TEST_MESSAGE);
        
        Writer out5 = getWriter(TEST_FILE, ISO_5);
        out5.write("string: " + cbuf.toString());
        writeBytes(out5, cbuf.array());
        out5.close();
    }
    
    private static Writer getWriter(String file, String encoding)
            throws UnsupportedEncodingException, FileNotFoundException {
        return new BufferedWriter(new OutputStreamWriter(new FileOutputStream(
                file), encoding));
    }
    
    private static CharBuffer getCharBuffer(String encoding, String data)
            throws CharacterCodingException {
        Charset charset = Charset.forName(encoding);
        CharsetDecoder decoder = charset.newDecoder();
        CharsetEncoder encoder = charset.newEncoder();

        ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(data));

        return decoder.decode(bbuf);
    }
    
    private static void writeBytes(Writer out, char[] chars) throws IOException {
        out.write("\nbyte: ");
        for (int i = 0; i < chars.length; i++) {
            out.write((byte)chars[i] + " ");
        }
        out.write("\nint: ");
        for (int i = 0; i < chars.length; i++) {
            out.write((int)chars[i] + " ");
        }
        out.write("\nchar: ");
        for (int i = 0; i < chars.length; i++) {
            out.write(chars[i] + " ");
        }
    }
}


Например здесь хочу получить букву "Ю", выдаёт в файл результат при encoding = Cyrillic (ISO):

string: Ю
byte: 46 
int: 1070 
char: Ю

Букву "Ю" он показывает правильно, но вот вместо "int: 1070" надо чтобы показало: "int: 206", поскольку зайдя по той ссылке, которую я указал в прошлом сообщении видно, что: 
0xCE    0x042E    #    CYRILLIC CAPITAL LETTER YU
где 0x042E как раз равняется выводимому "1070", а надо чтобы выводил бы 0xCE, т.е. "206", но не понимаю почему он выводит именно номер unicode (т.е. 1070), когда я ему вроде явно во всех местах указал, что это должен быть ISO-8859-5 (т.е. 206) ?

Добавлено через 4 минуты и 42 секунды
На всякий случай ещё импорты для приведённого выше кода:

Код

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;

Автор: LSD 12.5.2008, 12:00
Цитата(Kizja @  12.5.2008,  01:30 Найти цитируемый пост)
Букву "Ю" он показывает правильно, но вот вместо "int: 1070" надо чтобы показало: "int: 206", поскольку зайдя по той ссылке, которую я указал в прошлом сообщении видно, что: 0xCE    0x042E    #    CYRILLIC CAPITAL LETTER YUгде 0x042E как раз равняется выводимому "1070", а надо чтобы выводил бы 0xCE, т.е. "206", но не понимаю почему он выводит именно номер unicode (т.е. 1070), когда я ему вроде явно во всех местах указал, что это должен быть ISO-8859-5 (т.е. 206) ?

Он все выводит правильно. Строки в Java всегда хранятся в UTF-16 и приводя char к int, ты просто получаешь код символа в UTF-16.

Тебе же надо преобразовать символы (char) в байты (byte), которые будут содержать символы в нужной тебе кодировке.
Код

  public static void main(String[] args) throws Exception
  {
    char[] chars = {'Э', 'Ю', 'Я'};
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    OutputStreamWriter writer = new OutputStreamWriter(out, "ISO-8859-5");
    writer.write(chars);
    writer.flush();
    System.out.print("bytes: ");
    for(byte b : out.toByteArray())
    {
      System.out.printf("%02X ", 0xFF & b);
    }
    System.out.println();

    System.out.print("chars: ");
    for(char c : chars)
    {
      System.out.printf("%04X ", 0xFFFF & c);
    }
    System.out.println();
  }

Автор: Kizja 13.5.2008, 00:13
LSD, спасибо большое за помощь - теперь ясно, а то как-то с этими байтами, чарами запутался было совсем...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)