ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    Java: Росіяни букви і не тільки ...
         

     

    Інформатика, програмування

    Java: Росіяни букви і не тільки ...

    Введення

    Деякі проблеми настільки складні, що потрібно бути дуже розумним і дуже добре поінформованим, щоб не бути впевненим у їх вирішенні.

    Лоренс Дж. Пітер

    Peter's Almanac

    Кодування

    Коли я тільки починав програмувати на мові C, першою моєю програмою (не рахуючи HelloWorld) була програма перекодування текстових файлів з основної кодування ГОСТ-а (пам'ятаєте таку? :-) В альтернативне. Було це в далекому 1991-му році. З тих пір багато чого змінилося, але за минулі 10 років подібні програмки свою актуальність, на жаль, не втратили. Занадто багато вже накопичено даних у різноманітних кодуваннях і занадто багато використовується програм, які вміють працювати тільки з однією. Для російської мови існує не менше десятка різних кодувань, що робить проблему ще більш заплутаною.

    Звідки ж узялися всі ці кодування і для чого вони потрібні? Комп'ютери за своєю природою можуть працювати тільки з числами. Для того, щоб зберігати букви в пам'яті комп'ютера треба поставити у відповідність кожній букві певне число (приблизно такий же принцип використовувався і до появи комп'ютерів - згадайте про ту ж азбуку Морзе). Причому число бажано трохи менше - чим менше двійкових розрядів буде задіяно, тим ефективніше можна буде використовувати пам'ять. Ось це відповідність набору символів та чисел власне і є кодування. Бажання будь-якої ціною заощадити пам'ять, а так само роз'єднаність різних груп комп'ютерників і призвела до нинішнього стану справ. Найпоширенішим способом кодування зараз є використання для одного символу одного байти (8 біт), що визначає загальну кількість символів в 256. Набір перші 128 символів стандартизований (набір ASCII) і є однаковими у всіх поширених кодуваннях (ті кодування, де це не так вже практично вийшли з вжитку). Англіцкіе літери і символи пунктуації знаходяться в цьому діапазоні, що й визначає їх вражаючу живучість в комп'ютерних системах :-). Інші мови знаходяться не в настільки щасливому становищі - їм усім доводиться тулитися в останніх 128 числах.

    Unicode

    В Наприкінці 80-х багато хто усвідомив необхідність створення єдиного стандарту на кодування символів, що й призвело до появи Unicode. Unicode - це спроба раз і назавжди зафіксувати конкретне число за конкретним символом. Зрозуміло, що в 256 символів тут не укластися при всьому бажанні. Досить довгий час здавалося, що вже 2-х то байт (65536 символів) повинно вистачити. Але ж ні -- остання версія стандарту Unicode (3.1) визначає вже 94140 символів. Для такого кол-ва символів, напевно, вже доведеться використовувати 4 байти (4294967296 символів). Може бути і вистачить на деякий час ... :-)

    В набір символів Unicode входять всілякі літери з усякими рисками і пріпендюлькамі, грецькі, математичні, ієрогліфи, символи псевдографіки і пр. і пр. У тому числі і так улюблені нами символи кирилиці (діапазон значень 0x0400-0x04ff). Так що з цього боку ніякої дискримінації немає.

    Якщо Вам цікаві конкретні коду символів, для їх перегляду зручно використовувати програму "Таблиця символів" з WinNT. Ось, наприклад, діапазон кирилиці:

    Якщо у Вас інша OS або Вас цікавить офіційне тлумачення, то повну розкладку символів (charts) можна знайти на офіційному сайті Unicode (http://www.unicode.org/charts/web.html).

    Типи char і byte

    В Java для символів виділений окремий тип даних char розміром у 2 байти. Це часто породжує плутанину в умах початківців (особливо якщо вони раніше програмували на інших мовах, наприклад на C/C + +). Справа в тому, що в більшості інших мов для обробки символів використовуються типи даних розміром в 1 байт. Наприклад, в C/C + + тип char в більшості випадків використовується як для обробки символів, так і для обробки байтів - там немає поділу. У Java для байтів є свій тип - тип byte. Таким чином C-ішному char відповідає Java-київськи byte, а Java-вскому char зі світу C найближче тип wchar_t. Треба чітко розділяти поняття символів і байтів - інакше нерозуміння і проблеми гарантовані.

    Java практично з самого свого народження використовує для кодування символів стандарт Unicode. Бібліотечні функції Java очікують побачити в змінних типу char символи, представлені кодами Unicode. В принципі, Ви, звичайно, можете запхати туди що завгодно - цифри є цифри, процесор все стерпить, але при будь-якій обробці бібліотечні функції будуть діяти виходячи з припущення що їм передали кодування Unicode. Так що можна спокійно вважати, що у типу char кодування зафіксована. Але це всередині JVM. Коли дані читаються ззовні або передаються назовні, то вони можуть бути представлені тільки одним типом - типом byte. Всі інші типи конструюються з байтів в залежності від використовуваного формату даних. Ось тут на сцену і виходять кодування - в Java це просто формат даних для передачі символів, який використовується для формування даних типу char. Для кожної кодової сторінки в бібліотеці є по 2 класу перекодування (ByteToChar і CharToByte). Класи ці лежать в пакеті sun.io. Якщо, при перекодуванні з char в byte не було знайдено відповідного символу, він замінюється на символ?.

    До речі, ці файли кодових сторінок в деяких ранніх версіях JDK 1.1 містять помилки, викликають помилки перекодіровок, а то й взагалі виключення при виконанні. Наприклад, це стосується кодування KOI8_R. Найкраще, що можна при цьому зробити -- змінити версію на більш пізню. Судячи з Sun-івської опису, більшість цих проблем було вирішено у версії JDK 1.1.6.

    До появи версії JDK 1.4 набір доступних кодувань визначався тільки виробником JDK. Починаючи з 1.4 з'явилося нове API (пакет java.nio.charset), за допомогою якого Ви вже можете створити свою власну систему кодування (наприклад підтримати рідко використовувану, але моторошно необхідну саме Вам).

    Клас String

    В більшості випадків для подання рядків в Java використовується об'єкт типу java.lang.String. Це звичайний клас, який всередині себе зберігає масив символів (char []), і який містить багато корисних методів для маніпуляції символами. Найкращі цікаві - це конструктори, що мають перший параметром масив байтів (byte []) і методи getBytes (). За допомогою цих методів Ви можете виконувати перетворення з масиву байтів в рядки і назад. Для того, щоб вказати будь кодування при цьому використовувати у цих методів є рядковий параметр, який задає її ім'я. Ось, наприклад, як можна виконати перекодування байтів з КОИ-8 у Windows-1251:

    // Дані в кодуванні КОИ-8

    byte [] koi8Data = ...;

    // Перетворимо з КОИ-8 в Unicode

    String string = new String (koi8Data, "KOI8_R ");

    // Перетворимо з Unicode в Windows-1251

    byte [] winData = string.getBytes ( "Cp1251 ");

    Список 8-ми бітових кодувань, доступних в сучасних JDK і підтримують російські букви Ви можете знайти нижче, в розділі "8-ми бітові кодування росіян букв ".

    Так як кодування - це формат даних для символів, крім знайомих 8-ми бітових кодувань в Java також на рівних присутні і багатобайтове кодування. До таких відносяться UTF-8, UTF-16, Unicode і пр. Наприклад ось так можна отримати байти у форматі UnicodeLittleUnmarked (16-ти бітове кодування Unicode, молодший байт першим, без ознаки порядку байтів):

    // Рядок Unicode

    String string = "...";

    // Перетворимо з Unicode в UnicodeLittleUnmarked

    byte [] data = string.getBytes ( "UnicodeLittleUnmarked ");

    При подібних перетвореннях легко помилитися - якщо кодування байтових даних не відповідають вказаним параметром при перетворенні з byte в char, то перекодування буде виконано неправильно. Іноді після цього можна витягнути правильні символи, але частіше за все частина даних буде безповоротно втрачена.

    В реальної програмі явно вказувати кодову сторінку не завжди зручно (хоча більше надійно). Для цього була введена кодування за замовчуванням. За умовчанням вона залежить від системи і її установки (для російських віндів прийнята кодування Cp1251), і в старих JDK її можна змінити установкою системного властивості file.encoding. В JDK 1.3 зміна цієї налаштування іноді спрацьовує, іноді - ні. Викликано це в такий: спочатку file.encoding ставиться з регіональних налаштувань комп'ютера. Посилання на кодування за замовчуванням запам'ятовується в нутрії при першій перетворення. При цьому використовується file.encoding, але це перетворення відбувається ще до використання аргументів запуску JVM (собсно, при їх розборі). Взагалі-то, як стверджують в Sun, ця властивість відображає системну кодування, і вона не повинна змінюватися у командному рядку (див., наприклад, коментарі до BugID 4163515) Тим не менше у JDK 1.4 Beta 2 зміна цієї налаштування знову почала надавати ефект. Що це, свідома зміна або побічний ефект, який може знову зникнути - Sun-вівці чіткої відповіді поки що не дали.

    Ця кодування використовується тоді, коли явно не вказано назву сторінки. Про це треба завжди пам'ятати - Java не буде намагатися передбачити кодування байтів, які ви передаєте для створення рядка String (так само вона не зможе прочитати Ваші думки з цього приводу :-). Вона просто використовує поточну кодування за замовчуванням. Оскільки ця установка один на всі перетворення, іноді можна наразитися на неприємності.

    Для перетворення з байтів в символи і назад слід користуватися тільки цими методами. Просте приведення типу використовувати в більшості випадків не можна -- кодування символів при цьому не буде враховуватися. Наприклад, однією з найбільш поширених помилок є читання даних побайтно за допомогою методу read () з InputStream, а потім приведення отриманого значення до типу char:

    InputStream is = ..;

    int b;

    StringBuffer sb = new StringBuffer ();

    while ((b = is.read ())!=- 1)

    (

    sb.append ((char) b);// <- так робити не можна

    )

    String s = sb.toString ();

    Зверніть увагу на приведення типу - "(char) b". Значення байтів замість перекодування просто скопійовано в char (діапазон значень 0-0xFF, а не той, де знаходиться кирилиця). Такому копіюванню відповідає кодування ISO-8859-1 (яка один в один відповідає першій 256 значень Unicode), а отже, можна вважати, що цей код просто використовує її (замість тієї, в якій реально закодовані символи в оригінальних даних). Якщо Ви спробуєте відобразити отримане значення - на екрані буде або Вопросики або кракозябли. Наприклад, при читанні рядка "АБВ" в віндового кодуванні може запросто відобразитися щось на кшталт такого: "

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status