Računala Windows Internet

Ruska slova u tablici kodova sustava Windows. Kodiranje ćirilicom - ruski

Kodiranja

Kad sam tek počeo programirati na C -u, moj prvi program (osim HelloWorld -a) bio je program za kodiranje tekstualne datoteke od glavnog GOST kodiranja (sjećate li se ovog? :-) do alternativnog. Bilo je to davne 1991. godine. Od tada se mnogo toga promijenilo, ali nažalost takvi programi nisu izgubili na važnosti u posljednjih 10 godina. Previše je podataka već prikupljeno u različitim kodiranjima i koristi se previše programa koji mogu raditi samo s jednim. Za ruski jezik postoji najmanje desetak različitih kodiranja, što problem čini još zbunjujućim.

Odakle su došla ta kodiranja i čemu služe? Računala po svojoj prirodi mogu raditi samo s brojevima. Za spremanje slova u memoriju računala potrebno je svakom slovu dodijeliti određeni broj (otprilike isti princip je korišten prije pojavljivanja računala - zapamtite isti Morzeov kod). Štoviše, broj je poželjno manji - što je manje binarnih znamenki u pitanju, to se memorija može učinkovitije koristiti. Ova korespondencija između skupa znakova i brojeva zapravo je kodiranje. Želja da se pod svaku cijenu sačuva memorija, kao i nejedinstvo različitih skupina informatičara doveli su do trenutnog stanja. Najčešća metoda kodiranja sada je korištenje jednog bajta (8 bita) za jedan znak, što određuje ukupan broj znakova u 256. Skup prvih 128 znakova je standardiziran (skup ASCII) i isti je u svim uobičajenim kodiranjima (ona kodiranja gdje već nije tako praktički izvan upotrebe). Anglikanska slova i simboli interpunkcije nalaze se u ovom rasponu, što određuje njihovu nevjerojatnu preživljavanje u računalnim sustavima :-). Drugi jezici nisu tako sretni - svi se moraju zgrnuti u preostalih 128 brojeva.

Unicode

Krajem 1980 -ih mnogi su shvatili potrebu stvaranja jedinstvenog standarda za kodiranje znakova, što je dovelo do pojave Unicodea. Unicode je pokušaj da se jednom zauvijek popravi određeni broj za određeni znak. Jasno je da se 256 znakova ovdje neće uklopiti sa svom željom. Dugo se činilo da bi 2 bajta (65536 znakova) trebala biti dovoljna. Ali ne - najnovija verzija Unicode standarda (3.1) već definira 94.140 znakova. Za takav broj znakova vjerojatno već morate koristiti 4 bajta (4294967296 znakova). Možda dosta za neko vrijeme ... :-)

U set Unicode znakovi uključuje sve vrste slova sa svim vrstama crtica i papendyulki, grčkih, matematičkih, hijeroglifa, pseudo-grafičkih simbola itd. itd. Uključujući naše omiljene ćirilične znakove (raspon vrijednosti je 0x0400-0x04ff). Dakle, s ove strane nema diskriminacije.

Ako vas zanimaju posebni kodovi znakova, prikladno je koristiti program "Karta znakova" iz WinNT -a za njihov pregled. Na primjer, ovdje je raspon ćirilice:

Ako imate drugi OS ili ste zainteresirani za službeno tumačenje, tada se potpuni grafikoni mogu pronaći na službenoj web stranici Unicode (http://www.unicode.org/charts/web.html).

Vrste znakova i bajtova

Java ima zasebnu vrstu podataka char od 2 bajta za znakove. To često stvara zabunu u glavama početnika (osobito ako su prethodno programirali na drugim jezicima, poput C / C ++). To je zato što većina drugih jezika koristi 1-bajtne vrste podataka za obradu znakova. Na primjer, u C / C ++ tip char se u većini slučajeva koristi i za rukovanje znakovima i za rukovanje bajtovima - nema razdvajanja. Java ima svoj tip bajtova - tip bajtova. Dakle, char temeljen na C odgovara Java bajtu, a Java char iz svijeta C najbliži je tipu wchar_t. Potrebno je jasno razdvojiti pojmove znakova i bajtova - u protivnom su nesporazumi i problemi zajamčeni.

Java se koristi za kodiranje znakova gotovo od svog početka Unicode standard... Funkcije Java knjižnice očekuju da će znakovi char biti predstavljeni sa Unicode kodovi... U načelu, naravno, tamo možete ubaciti bilo što - brojevi su brojevi, procesor će izdržati sve, ali za svaku obradu, funkcije knjižnice djelovat će pod pretpostavkom da su date Unicode kodiranje... Stoga možete sa sigurnošću pretpostaviti da je kodiranje znakova fiksno. Ali ovo je unutar JVM -a. Kada se podaci čitaju izvana ili prosljeđuju izvana, tada se mogu predstaviti samo jednom vrstom - vrstom bajta. Svi ostali tipovi izrađeni su od bajtova, ovisno o formatu podataka koji se koristi. Ovdje kodiranje dolazi u obzir - u Javi je to samo format podataka za prijenos znakova, koji se koristi za formiranje podataka tipa char. Za svaku kodnu stranicu u knjižnici postoje 2 razreda pretvorbe (ByteToChar i CharToByte). Ove klase su u paketu sun.io. Ako pri pretvaranju iz char u bajt nije pronađen odgovarajući znak, zamjenjuje se znakom?

Usput, ove datoteke kodnih stranica u nekim ranijim verzijama JDK 1.1 sadrže greške koje uzrokuju pogreške pretvorbe ili čak iznimke za vrijeme izvođenja. Na primjer, ovo se odnosi na kodiranje KOI8_R. Najbolje što trebate učiniti je promijeniti verziju na kasniju. Na temelju Sunčevog opisa, većina ovih problema riješena je u JDK 1.1.6.

Prije JDK 1.4, skup dostupnih kodiranja odredio je samo dobavljač JDK. Počevši od 1.4, pojavio se novi API (paket java.nio.charset), s kojim već možete stvoriti vlastito kodiranje (na primjer, podržati rijetko korišteno, ali užasno potrebno za vas).

Klasa niza

U većini slučajeva Java koristi objekt tipa java.lang.String za predstavljanje nizova. Ovo je redovna klasa koja interno pohranjuje niz znakova (char) i koja sadrži mnoge korisne metode za upravljanje znakovima. Najzanimljiviji su konstruktori s nizom bajtova kao prvim parametrom i metode getBytes (). Pomoću ovih metoda možete izvesti pretvorbe iz nizova bajtova u nizove i obrnuto. Kako bi se odredilo koje će se kodiranje koristiti u isto vrijeme, ove metode imaju parametar niza koji postavlja njegovo ime. Na primjer, evo kako možete pretvoriti bajte iz KOI-8 u Windows-1251:

// Podaci kodirani KOI-8 bajt koi8Data = ...; // Pretvori iz KOI-8 u Unicode String string = new String (koi8Data, "KOI8_R"); // Pretvorba iz Unicodea u Windows-1251 bajt winData = string.getBytes ("Cp1251");

Popis 8-bitnih kodiranja dostupnih u modernim JDK-ovima i koji podržavaju ruska slova nalazi se ispod, u odjeljku.

Budući da je kodiranje format podataka za znakove, osim poznatih 8-bitnih kodiranja u Javi, postoje i višekodirana kodiranja na jednakim osnovama. To uključuje UTF-8, UTF-16, Unicode itd. Na primjer, ovako možete dobiti bajtove u formatu UnicodeLittleUnmarked (16-bitno kodiranje Unicode, prvo niskobajtno, bez znaka za poredak bajtova):

// Pretvoriti iz Unicode u Unicode data byte = string.getBytes ("UnicodeLittleUnmarked");

Lako je pogriješiti s takvim konverzijama - ako kodiranje podataka bajta ne odgovara navedenom parametru pri pretvaranju iz bajta u char, tada se prepisivanje neće izvršiti ispravno. Ponekad nakon toga možete izvući ispravne znakove, no češće će se dio podataka nepovratno izgubiti.

U stvarnom programu nije uvijek zgodno navesti kodnu stranicu izričito (iako je pouzdanija). Za to je uvedeno zadano kodiranje. Prema zadanim postavkama, to ovisi o sustavu i njegovim postavkama (za ruski Windows, kodiranje Cp1251 je usvojeno), a u starim JDK -ovima može se promijeniti postavljanjem datoteke svojstava sustava.kodiranje. U JDK 1.3, promjena ove postavke ponekad funkcionira, ponekad ne. To je uzrokovano sljedećim: u početku se datotečno kodiranje postavlja prema regionalnim postavkama računala. Zadana referenca kodiranja interno se pamti tijekom prve pretvorbe. U ovom slučaju koristi se file.encoding, no do ove se konverzije dolazi čak i prije korištenja argumenata za pokretanje JVM -a (zapravo, prilikom njihovog raščlanjivanja). Zapravo, kaže Sun, ovo svojstvo odražava kodiranje sustava i ne treba ga mijenjati u naredbenom retku (vidi, na primjer, komentare na BugID). Međutim, u JDK 1.4 Beta 2, promjena ove postavke ponovno je imala učinka. Što je ovo, svjesna promjena ili nuspojava koja može opet nestati - Sunčeve ovce još nisu dale jasan odgovor.

Ovo kodiranje se koristi kada naziv stranice nije izričito naveden. To uvijek treba zapamtiti - Java neće pokušati predvidjeti kodiranje bajtova koje proslijedite za stvaranje Stringa (također neće moći pročitati vaša razmišljanja o tome :-). Koristi samo trenutno zadano kodiranje. Jer ova je postavka ista za sve transformacije, ponekad možete naići na probleme.

Za pretvaranje iz bajtova u znakove i obrnuto koristite samo ovim metodama. U većini slučajeva ne može se koristiti jednostavna pretvorba tipa - kodiranje znakova neće se uzeti u obzir. Na primjer, jedna od najčešćih grešaka je čitanje podataka po bajtovima pomoću metode read () iz InputStream-a, a zatim dobivena vrijednost prebacivanje na tip char:

Ulazni tok je = ..; int b; StringBuffer sb = novi StringBuffer (); while ((b = is.read ())! = - 1) (sb.append ((char) b); // <- так делать нельзя ) Niz s = sb.toString ();

Obratite pažnju na tipkanje - "(char) b". Vrijednosti bajtova jednostavno se kopiraju u char umjesto ponovnog kodiranja (raspon vrijednosti je 0-0xFF, a ne onaj gdje je ćirilica). Ovo kopiranje odgovara kodiranju ISO-8859-1 (koje jedan na jedan odgovara prvim 256 Unicode vrijednostima), što znači da možemo pretpostaviti da ga ovaj kôd jednostavno koristi (umjesto onog u kojem su znakovi u izvorni podaci su zapravo kodirani). Ako pokušate prikazati primljenu vrijednost, na zaslonu će se pojaviti pitanja ili krakozjabilno. Na primjer, pri čitanju niza "ABC" u kodiranju sustava Windows može se lako prikazati nešto poput ovoga: "AV". Ovu vrstu koda često pišu programeri na Zapadu - radi s engleskim slovima, i u redu. Popravljanje ovog koda je jednostavno - samo trebate zamijeniti StringBuffer s ByteArrayOutputStream:

Ulazni tok je = ..; int b; ByteArrayOutputStream baos = novi ByteArrayOutputStream (); while ((b = is.read ())! = - 1) (baos.write (b);) // Pretvorba bajtova u niz pomoću zadanog kodiranja Niz s = baos.toString (); // Ako vam je potrebno posebno kodiranje, samo ga navedite prilikom pozivanja toString (): // // s = baos.toString ("Cp1251");
Za više informacija o uobičajenim pogreškama pogledajte odjeljak.

8-bitno kodiranje ruskih slova

Evo glavnih 8-bitnih kodiranja ruskih slova koja su postala široko rasprostranjena:

Osim glavnog naziva, mogu se koristiti i sinonimi. Njihov skup može se razlikovati u različitim verzijama JDK -a. Evo popisa iz JDK 1.3.1:

  • CP1251:
    • Windows-1251
  • CP866:
    • IBM866
    • IBM-866
    • CP866
    • CSIBM866
  • KOI8_R:
    • KOI8-R
    • CSKOI8R
  • ISO8859_5:
    • ISO8859-5
    • ISO-8859-5
    • ISO_8859-5
    • ISO_8859-5: 1988
    • ISO-IR-144
    • 8859_5
    • Ćirilica
    • CSISOLatinCirilica
    • IBM915
    • IBM-915
    • Cp915

Štoviše, sinonimi, za razliku od glavnog naziva, ne razlikuju velika i mala slova - to je značajka implementacije.

Vrijedi napomenuti da ova kodiranja možda nisu dostupna na nekim JVM -ovima. Na primjer, možete preuzeti dvije različite verzije JRE -a sa Sun -ove web stranice, američku i međunarodnu. U američkoj verziji postoji samo minimum-ISO-8859-1, ASCII, Cp1252, UTF8, UTF16 i nekoliko varijacija dvobajtnog Unicodea. Sve ostalo dostupno je samo u međunarodnoj verziji. Ponekad zbog toga možete naletjeti na grablje s pokretanjem programa, čak i ako ne trebaju ruska slova. Tipična greška koja se događa dok to radite:

Došlo je do pogreške tijekom inicijalizacije VM java / lang / ClassNotFoundException: sun / io / ByteToCharCp1251

Nastaje, kako nije teško pogoditi, zbog činjenice da JVM, na temelju ruskih regionalnih postavki, pokušava postaviti zadano kodiranje u Cp1251, ali budući da klasa takve podrške nema u američkoj verziji, prirodno se prekida.

Datoteke i podatkovni tokovi

Baš kao što su bajtovi konceptualno odvojeni od znakova, Java razlikuje tokove bajtova i znakove. Rad s bajtovima predstavljen je klasama koje izravno ili neizravno nasljeđuju klase InputStream ili OutputStream (plus jedinstvena klasa RandomAccessFile). Rad sa simbolima predstavlja slatki par razreda Čitatelj / Pisac (i njihovi potomci, naravno).

Nizovi bajtova koriste se za čitanje / pisanje nepreobraćenih bajtova. Ako znate da bajtovi predstavljaju samo znakove u određenom kodiranju, možete koristiti posebne klase pretvarača InputStreamReader i OutputStreamWriter da biste dobili niz znakova i izravno radili s njima. To je obično korisno za datoteke s običnim tekstom ili pri radu s mnogim internetskim mrežnim protokolima. U ovom slučaju kodiranje znakova je navedeno u konstruktoru klase pretvarača. Primjer:

// Unicode niz String string = "..."; // Zapišite niz u tekstualnu datoteku u kodiranju Cp866 PrintWriter pw = novi PrintWriter // klasa s metodama za pisanje nizova(novi OutputStreamWriter // klasa-pretvarač(novi FileOutputStream ("file.txt"), "Cp866"); pw.println (niz); // zapisujemo redak u datoteku pw.close ();

Ako tok može sadržavati podatke u različitim kodiranjima ili su znakovi pomiješani s drugim binarnim podacima, onda je bolje čitati i pisati nizove bajtova (bajtova), a za pretvorbu koristiti već spomenute metode klase String. Primjer:

// Unicode niz String string = "..."; // Zapišite niz u tekstualnu datoteku u dva kodiranja (Cp866 i Cp1251) OutputStream os = novi FileOutputStream ("file.txt"); // klasa za upisivanje bajtova u datoteku // Zapišite niz u kodiranju Cp866 os.write (string.getBytes ("Cp866")); // Zapišite niz u kodiranju Cp1251 os.write (string.getBytes ("Cp1251")); os.close ();

Konzola u Javi tradicionalno je predstavljena tokovima, ali, nažalost, ne znakovima, već bajtovima. Činjenica je da su se znakovni tokovi pojavili samo u JDK 1.1 (zajedno s cijelim mehanizmom kodiranja), a pristup konzoli I / O je dizajniran u JDK 1.0, što je dovelo do pojave čudaka u obliku klase PrintStream. Ova se klasa koristi u varijablama System.out i System.err, koje zapravo daju pristup izlazu na konzolu. Po svemu sudeći, ovo je niz bajtova, ali s hrpom metoda za pisanje nizova. Kad u njega upišete niz, on se pretvara u bajte pomoću zadanog kodiranja, što je obično neprihvatljivo u slučaju sustava Windows - zadano kodiranje bit će Cp1251 (Ansi), a za prozor konzole obično morate koristiti Cp866 ( OEM). Ova je pogreška registrirana još 97. godine (), ali čini se da Sun-ovce ne žure sa ispravljanjem. Budući da ne postoji metoda za postavljanje kodiranja u PrintStreamu, za rješavanje ovog problema možete zamijeniti standardnu ​​klasu vlastitom pomoću metoda System.setOut () i System.setErr (). Na primjer, evo uobičajenog početka u mojim programima:

... javni statički void main (String args) ( // Postavite izlaz konzolnih poruka u željenom kodiranju pokušajte (String consoleEnc = System.getProperty ("console.encoding", "Cp866"); System.setOut (novi CodepagePrintStream (System.out, consoleEnc)); System.setErr (novi CodepagePrintStream (System.err, consoleEnc)); ) catch (UnsupportedEncodingException e) (System.out.println ("Nije moguće postaviti kodnu stranicu konzole:" + e);) ...

Izvore klase CodepagePrintStream možete pronaći na ovoj web stranici: CodepagePrintStream.java.

Ako sami konstruirate format podataka, preporučujem da upotrijebite jedno od višebajtnih kodiranja. Najprikladniji format obično je UTF8 - prvih 128 vrijednosti (ASCII) u njemu kodirano je u jednom bajtu, što često može značajno smanjiti ukupnu količinu podataka (nije uzalud to kodiranje uzeto kao osnova u XML svijet). No, UTF8 ima jedan nedostatak - broj potrebnih bajtova ovisi o kodu znaka. Tamo gdje je to kritično, možete koristiti jedan od dvobajtnih formata Unicode (UnicodeBig ili UnicodeLittle).

Baza podataka

Za ispravno čitanje znakova iz baze podataka obično je dovoljno reći JDBC pogonitelju potrebno kodiranje znakova u bazi podataka. Kako točno ovisi o konkretnom vozaču. Danas mnogi vozači već podržavaju ovu postavku, za razliku od nedavne prošlosti. Evo nekoliko primjera za koje znam.

JDBC-ODBC most

Ovo je jedan od najčešće korištenih upravljačkih programa. Most iz JDK 1.2 i starije može se jednostavno konfigurirati na željeno kodiranje. To se postiže dodavanjem dodatnog svojstva charSet u skup parametara proslijeđenih za otvaranje veze s bazom. Zadana vrijednost je file.encoding. Ovo se radi otprilike ovako:

// Uspostavite vezu

Oracle 8.0.5 JDBC-OCI upravljački program za Linux

Prilikom primanja podataka iz baze podataka, ovaj upravljački program određuje "svoje" kodiranje pomoću varijable okruženja NLS_LANG. Ako se ova varijabla ne pronađe, pretpostavlja se da je kodiranje ISO-8859-1. Trik je u tome što bi NLS_LANG trebala biti varijabla okruženja (postavljena naredbom set), a ne svojstvo Java sustava (poput file.encoding). U slučaju korištenja pogonitelja unutar stroja servera Apache + Jserv, varijablu okruženja možete postaviti u datoteci jserv.properties:

omot.env = NLS_LANG = Američka_Amerika.CL8KOI8R
Informaciju o tome poslao je Sergej Bezrukov, na čemu mu posebno zahvaljuje.

JDBC upravljački program za rad s DBF -om (zyh.sql.dbf.DBFDriver)

Ovaj je vozač tek nedavno naučio raditi s ruskim slovima. Iako je putem getPropertyInfo () izvijestio da razumije svojstvo charSet, to je fikcija (barem u verziji od 30.7.2001.). U stvarnosti, kodiranje možete prilagoditi postavljanjem svojstva CODEPAGEID. Za ruske znakove dostupne su dvije vrijednosti - "66" za Cp866 i "C9" za Cp1251. Primjer:

// Osnovni parametri povezivanja Svojstva connInfo = nova svojstva (); connInfo.put ("CODEPAGEID", "66"); // Cp866 kodiranje // Uspostavite vezu Veza db = DriverManager.getConnection ("jdbc: DBF: / C: / MyDBFFiles", connInfo);
Ako imate DBF datoteke FoxPro formata, onda one imaju svoje specifičnosti. Činjenica je da FoxPro sprema u zaglavlje datoteke ID kodne stranice (bajt s pomakom 0x1D), koji je korišten za stvaranje DBF -a. Prilikom otvaranja tablice, upravljački program koristi vrijednost iz zaglavlja, a ne parametar "CODEPAGEID" (parametar se u ovom slučaju koristi samo pri stvaranju novih tablica). U skladu s tim, kako bi sve radilo ispravno, DBF datoteka mora biti stvorena s ispravnim kodiranjem - inače će doći do problema.

MySQL (org.gjt.mm.mysql.Driver)

S ovim upravljačkim programom sve je također prilično jednostavno:

// Osnovni parametri povezivanja Svojstva connInfo = nove osobine (); connInfo.put ("korisnik", korisnik); connInfo.put ("lozinka", prolaz); connInfo.put ("useUnicode", "true"); connInfo.put ("characterEncoding", "KOI8_R"); Veza conn = DriverManager.getConnection (dbURL, rekviziti);

InterBase (interbase.interclient.Driver)

Za ovaj upravljački program radi parametar "charSet":
// Osnovni parametri povezivanja Svojstva connInfo = nova svojstva (); connInfo.put ("korisnik", korisničko ime); connInfo.put ("lozinka", lozinka); connInfo.put ("charSet", "Cp1251"); // Uspostavite vezu Veza db = DriverManager.getConnection (dataurl, connInfo);

Međutim, ne zaboravite navesti kodiranje znakova pri stvaranju baze podataka i tablica. Za ruski jezik možete koristiti vrijednosti "UNICODE_FSS" ili "WIN1251". Primjer:

CREATE DATABASE "E: \ ProjectHolding \ DataBase \ HOLDING.GDB" PAGE_SIZE 4096 ZADOVOLJNI NIZ ZNAKA UNICODE_FSS; CREATE TABLE RUSSIAN_WORD ("NAME1" VARCHAR (40) CHARACTER SET UNICODE_FSS NOT NULL, "NAME2" VARCHAR (40) CHARACTER SET WIN1251 NOT NULL, PRIMARY KEY ("NAME1"));

Postoji greška u verziji 2.01 InterClienta - klase resursa s porukama za ruski jezik tamo nisu pravilno sastavljene. Najvjerojatnije su programeri jednostavno zaboravili navesti izvorno kodiranje pri prevođenju. Postoje dva načina za ispravljanje ove pogreške:

  • Koristite interclient-core.jar umjesto interclient.jar. Istodobno, jednostavno neće biti ruskih resursa, a engleski će se automatski pokupiti.
  • Ponovno kompajlirajte datoteke u uobičajeni Unicode. Raščlanjivanje datoteka klasa nezahvalan je zadatak, pa je bolje koristiti JAD. Nažalost, JAD, ako naiđe na znakove iz skupa ISO-8859-1, emitira ih u 8-znamenkasti kodiranju, tako da nećete moći koristiti standardni native2ascii koder-morate napisati vlastiti (Decode program). Ako se ne želite zamarati tim problemima, možete uzeti gotovu datoteku s resursima (zakrpljena staklenka s upravljačkim programom - interclient.jar, zasebne klase resursa - interclient -rus.jar).

No čak i ako ste JDBC upravljački program podesili na željeno kodiranje, u nekim slučajevima možete naići na probleme. Na primjer, kada pokušavate koristiti prekrasne nove kursore za pomicanje standarda JDBC 2 u JDBC-ODBC mostu iz JDK 1.3.x, brzo ćete otkriti da ruska slova tamo jednostavno ne funkcioniraju (metoda updateString ()).

S ovom greškom povezana je mala priča. Kad sam ga prvi put otkrio (pod JDK 1.3 rc2), registrirao sam ga na BugParade (). Kada je izašla prva beta verzija JDK 1.3.1, ova je greška označena kao popravljena. Oduševljen, preuzeo sam ovu beta verziju, pokrenuo test - ne radi. O tome sam pisao Sun -ovci - u odgovoru su mi napisali da će popravak biti uključen u buduća izdanja. U redu, pomislio sam, pričekajmo. Vrijeme je prolazilo, objavljeno je izdanje 1.3.1, a zatim beta 1.4. Konačno sam odvojio vrijeme za provjeru - opet ne radi. Majko, majko, majko ... - odjek je odjeknuo uobičajeno. Nakon ljutitog pisma Suncu, uveli su novu grešku (), koju su dali indijskoj grani da je rastrga. Indijanci su petljali po kodu i rekli da je sve popravljeno u 1.4 beta3. Skinuo sam ovu verziju, pokrenuo testni slučaj ispod nje, evo rezultata -. Kako se ispostavilo, beta3 koji se distribuira na web mjestu (build 84) nije beta3 u koji je uključeno konačno popravljanje (build 87). Sada obećavaju da će popravak biti uključen u 1.4 rc1 ... Pa, općenito, razumijete :-)

Ruska slova u izvorima Java programa

Kao što je spomenuto, program prilikom izvođenja koristi Unicode. Izvorne datoteke zapisane su u običnim urednicima. Ja koristim Far, vjerojatno imate svog omiljenog urednika. Ovi uređivači spremaju datoteke u 8-bitnom formatu, što znači da se slično zaključivanje primjenjuje i na ove datoteke. Različite verzije prevoditelja izvode konverziju znakova nešto drugačije. Ranije verzije JDK 1.1.x koriste postavku file.encoding, koja se može nadjačati nestandardnom opcijom -J. U novijim (kako je izvijestio Denis Kokarev - počevši od 1.1.4) uveden je dodatni parametar -kodiranja, s kojim možete navesti kodiranje koje se koristi. U prevedenim razredima nizovi su predstavljeni u obliku Unicodea (točnije, u izmijenjenoj verziji UTF8 formata), pa se najzanimljivije događa tijekom kompilacije. Stoga je najvažnije saznati u kojem kodiranju vaše izvorne kodove i navesti točnu vrijednost prilikom sastavljanja. Prema zadanim postavkama koristit će se isti ozloglašeni file.encoding. Primjer pozivanja prevoditelja:

Osim korištenja ove postavke, postoji još jedna metoda - navođenje slova u "\ uXXXX" formatu, gdje je naznačen kod znaka. Ova metoda radi sa svim verzijama, a za dobivanje ovih kodova možete koristiti standardni alat.

Ako koristite bilo koji IDE, on može imati vlastite greške. Često ovi IDE -i koriste zadano kodiranje za čitanje / spremanje izvora - stoga obratite pozornost na regionalne postavke vašeg OS -a. Osim toga, mogu postojati očite pogreške - na primjer, prilično dobar CodeGuide IDE -skale ne probavlja dobro veliko rusko slovo "T". Ugrađeni analizator koda uzima ovo slovo kao dvostruki navodnik, što dovodi do činjenice da se ispravan kôd smatra pogrešnim. Možete se boriti protiv toga (zamjenom slova "T" njegovim kodom "\ u0422"), ali neugodno. Očigledno se negdje unutar raščlanjivača koristi eksplicitna pretvorba znakova u bajtove (poput: bajta b = (bajt) c), pa je umjesto koda 0x0422 (kôd slova "T") kôd 0x22 ( kod dvostrukog navodnika).

JBuilder ima još jedan problem, ali više je povezan s ergonomijom. Činjenica je da u JDK 1.3.0, pod kojim JBuilder radi prema zadanim postavkama, postoji greška () zbog koje novonastali prozori grafičkog sučelja, kada se aktiviraju, automatski uključuju raspored tipkovnice ovisno o regionalnim postavkama OS -a. Oni. ako imate ruske regionalne postavke, tada će se stalno pokušavati prebaciti na ruski izgled, što vam smeta pri pisanju programa. Web mjesto JBuilder.ru ima nekoliko zakrpa koje mijenjaju trenutnu lokaciju u JVM -u u Locale.US, ali najbolji način je nadogradnja na JDK 1.3.1, koja je ispravila ovu grešku.

Korisnici početnici JBuilder -a također mogu naići na takav problem - ruska slova se spremaju kao kodovi "\ uXXXX". Da biste to izbjegli, u dijaloškom okviru Zadana svojstva projekta, kartica Općenito, u polju Kodiranje promijenite Zadano u Cp1251.

Ako za kompilaciju koristite ne standardni javac, već neki drugi prevoditelj - obratite pozornost na to kako izvodi konverziju znakova. Na primjer, neke verzije kompajlera IBM jikes ne razumiju da postoje druga kodiranja osim ISO-8859-1 :-). Postoje zakrpljene verzije u tom smislu, ali često se tu šiva i neko kodiranje - nema takve pogodnosti kao u javac.

JavaDoc

Za generiranje HTML dokumentacije za izvorni kod koristi se javadoc uslužni program koji je uključen u standardnu ​​JDK distribuciju. Za navođenje kodiranja ima čak 3 parametra:

  • -encoding - ova postavka navodi izvorno kodiranje. Zadana vrijednost je file.encoding.
  • -docencoding - ova postavka specificira kodiranje generiranih HTML datoteka. Zadana vrijednost je file.encoding.
  • -charset - ova postavka određuje skup znakova koji će biti zapisan u zaglavlja generiranih HTML datoteka ( ). Očito bi trebalo biti isto kao i prethodna postavka. Ako je ova postavka izostavljena, meta oznaka neće biti dodana.

Ruska slova u datotekama svojstava

Metode učitavanja resursa koriste se za čitanje datoteka svojstava koja rade na određeni način. Zapravo se za čitanje koristi metoda Properties.load koja ne koristi file.encoding (izvorni kod je tvrdo kodiran s ISO-8859-1 kodiranjem), pa je jedini način za navođenje ruskih slova korištenje "\ uXXXX" format i uslužni program.

Metoda Properties.save drugačije funkcionira u JDK 1.1 i 1.2. U verzijama 1.1 jednostavno je odbacio visoki bajt pa je ispravno radio samo s engleskim slovima. 1.2 vrši obrnutu pretvorbu u "\ uXXXX" tako da radi preslikano na metodu učitavanja.

Ako se datoteke svojstava ne učitavaju kao resursi, već kao obične konfiguracijske datoteke, a niste zadovoljni takvim ponašanjem, postoji samo jedan izlaz, napišite vlastiti učitavač.

Ruska slova u Servletima.

Pa, čemu služe ti isti Servleti, mislim da znate. Ako ne, najbolje je prvo pročitati dokumentaciju. Ovdje su opisane samo osobitosti rada s ruskim slovima.

Koje su značajke? Kada Servlet pošalje odgovor klijentu, postoje dva načina za slanje tog odgovora - putem OutputStream (metoda getOutputStream ()) ili putem PrintWriter (getWriter () metoda). U prvom slučaju pišete nizove bajtova, pa su gornje metode pisanja u streamove primjenjive. U slučaju PrintWriter -a, koristi postavljeno kodiranje. U svakom slučaju, potrebno je ispravno navesti kodiranje koje se koristi pri pozivanju metode setContentType (), kako bi se ispravna pretvorba znakova izvršila na strani poslužitelja. Ova se direktiva mora napraviti prije poziva getWriter () ili prije prvog pisanja u OutputStream. Primjer:

// Postavljanje kodiranja odgovora // Imajte na umu da neki motori ne dopuštaju // razmak između ";" i "charset" response.setContentType ("text / html; charset = UTF-8"); PrintWriter out = response.getWriter (); // Otklanjanje pogrešaka imena kodiranja za provjeru out.println ("Kodiranje:" + odgovor.getCharacterEncoding ()); ... out.close (); )

Radi se o davanju odgovora klijentu. Nažalost, to nije tako jednostavno s ulaznim parametrima. Ulazni parametri kodirani su bajtom preglednika prema MIME vrsti "application / x-www-form-urlencoded". Kao što je rekao Aleksej Mendelev, preglednici kodiraju ruska slova koristeći trenutno postavljeno kodiranje. I, naravno, o tome se ništa ne izvještava. Sukladno tome, na primjer, u verzijama JSDK od 2.0 do 2.2, to se ni na koji način ne provjerava, a kakvo će se kodiranje koristiti za pretvorbu, ovisi o motoru koji se koristi. Počevši sa specifikacijom 2.3, postalo je moguće postaviti kodiranje za javax.servlet.ServletRequest - metodu setCharacterEncoding (). Najnovije verzije Resina i Tomcata već podržavaju ovu specifikaciju.

Dakle, ako imate sreće i imate poslužitelj s podrškom za Servlet 2.3, onda je sve vrlo jednostavno:

public void doPost (zahtjev HttpServletRequest, odgovor HttpServletResponse) baca ServletException, IOException ( // Kodiranje poruke request.setCharacterEncoding ("Cp1251"); Vrijednost niza = request.getParameter ("vrijednost"); ...

Postoji jedna značajna suptilnost u primjeni metode request.setCharacterEncoding () - ona se mora primijeniti prije prvi poziv na zahtjev za podacima (na primjer, request.getParameter ()). Ako koristite filtre koji obrađuju zahtjev prije nego što stigne u servlet, postoji šansa koja nije jednaka nuli da se u jednom od filtera neki parametar može pročitati iz zahtjeva (na primjer, za autorizaciju) i request.setCharacterEncoding () u servlet neće raditi ...

Stoga je ideološki ispravnije napisati filtar koji postavlja kodiranje zahtjeva. Štoviše, mora biti prvi u lancu filtara u web.xml.

Primjer takvog filtra:

uvoz java.io. *; uvoz java.util. *; uvoz javax.servlet. *; uvoz javax.servlet.http. *; javna klasa CharsetFilter implementira Filter (// kodira privatno kodiranje Stringa; javna void init (FilterConfig config) baca ServletException ( // čitanje iz konfiguracije encoding = config.getInitParameter ("requestEncoding"); // ako nije instaliran, instalirajte Cp1251 if (encoding == null) encoding = "Cp1251"; ) public void doFilter (ServletRequest zahtjev, ServletResponse odgovor, FilterChain next) baca IOException, ServletException (request.setCharacterEncoding (encoding); next.doFilter (zahtjev, odgovor);) public void kill () ())

I njegova konfiguracija u web.xml:

Filter znakova CharsetFilter Filter znakova /*

Ako nemate sreće i imate ih još stara verzija- da biste postigli rezultat, morate izopačiti:

    Izvorni način rada s kodiranjima nudi ruski Apache - opisano je točno kako.

  • FOP

    Ako program nigdje ne radi, problem je samo u njemu i u vašim rukama. Pažljivo pročitaj sve gore napisano i pogledaj. Ako se problem očituje samo u određenom okruženju, problem može biti u postavkama. Gdje točno ovisi o tome koju grafičku biblioteku koristite. Ako AWT - ispravna konfiguracija datoteke font.properties.ru može pomoći. Primjer valjane datoteke može se uzeti s Jave 2. Ako nemate ovu verziju, možete je preuzeti s ove web stranice: Verzija sustava Windows, Verzija Linuxa (vidi također dolje). Ova datoteka navodi fontove i kodne stranice koje ćete koristiti. Ako imate instaliranu rusku verziju OS -a, samo dodajte ovu datoteku na mjesto gdje se nalazi datoteka font.properties. Ako je ovo engleska verzija, morate ili prepisati ovu datoteku umjesto font.properties ili dodatno promijeniti trenutne regionalne postavke na ruski. Ponekad bi postavka -Duser.language = ru mogla funkcionirati, ali češće ne. Postoje približno isti problemi kao kod file.encoding - radi li ili ne ovisi o JDK -u (pogledajte pogrešku prema broju).

    S knjižnicom Swing sve je jednostavnije - u njoj je sve nacrtano kroz Java2D podsustav. Vrlo je jednostavno pretvoriti oznake u standardnim dijalozima (JOptionPane, JFileChooser, JColorChooser) u ruski - samo trebate stvoriti nekoliko datoteka resursa. To sam već učinio, pa možete uzeti gotovu datoteku i dodati je u lib \ ext ili CLASSPATH. Jedini problem s kojim sam se susreo je to što se u verzijama JDK -a, počevši od 1.2 rc1 i 1.3 beta, ruska slova ne prikazuju pod Win9x pri korištenju standardnih fontova (Arial, Courier New, Times New Roman itd.) Zbog greške u Java2D. Pogreška je prilično osebujna - sa standardnim fontovima slike slova ne prikazuju se prema Unicode kodovima, već prema tablici Cp1251 ( Ansi kodiranje). Ovaj je bug registriran u BugParade pod brojem. Prema zadanim postavkama, Swing koristi fontove navedene u datoteci font.properties.ru, pa ih je dovoljno zamijeniti drugim i pojavit će se ruska slova. Nažalost, skup radnih fontova je mali - to su fontovi Tahoma, Tahoma Bold i dva skupa fontova iz distribucije JDK - Lucida Sans * i Lucida Typewriter * (primjer datoteke font.properties.ru). Po čemu se ti fontovi razlikuju od standardnih, nije mi jasno.

    Od verzije 1.3rc1 ovaj je problem već riješen, pa samo trebate ažurirati JDK. JDK 1.2 je već jako zastario, pa ga ne preporučam koristiti. Također treba napomenuti da se izvorna verzija Win95 isporučuje sa fontovima koji ne podržavaju Unicode - u ovoj situaciji možete jednostavno kopirati fontove iz Win98 ili WinNT.

    Tipične greške ili "gdje je nestalo slovo W?"

    Slovo Sh.

    Ovo pitanje ("gdje je nestalo slovo W?") Početnici Java programeri često postavljaju. Da vidimo gdje to doista najčešće ide. :-)

    Evo tipičnog programa u stilu HelloWorld:

    test javne klase (public static void main (String args) (System.out.println ("ICUKENGŠЩZHʺЪ");))
    in Far, spremite ovaj kôd u datoteku Test.java, kompajlirajte ...
    C: \> javac Test.java
    i trči ...
    C: \> java Test YTsUKENG? ЩZHʺ.

    Što se dogodilo? Gdje je nestalo slovo W? Trik je u tome što je došlo do međusobne kompenzacije dviju grešaka. Uređivač dalekog teksta prema zadanim postavkama stvara DOS-kodiranu datoteku (Cp866). Prevoditelj javac koristi file.encoding za čitanje izvora (osim ako nije drugačije određeno ključem -encoding). I u Windows okruženje s ruskim jezikom zadano kodiranje je Cp1251. Ovo je prva greška. Zbog toga simboli u prevedenoj datoteci Test.class imaju netočne kodove. Druga je pogreška što se za ispis koristi standardni PrintStream, koji također koristi postavku iz file.encoding, ali prozor Windows konzole prikazuje znakove pomoću DOS kodiranja. Da je kodiranje Cp1251 međusobno valjano, ne bi došlo do gubitka podataka. Ali znak W u Cp866 ima kod 152, koji nije definiran u Cp1251, pa se stoga preslikava u Unicode znak 0xFFFD. Prilikom pretvaranja iz char u bajt, zamjenjuje se "?".

    Na sličnu kompenzaciju možete naići ako čitate znakove iz tekstualne datoteke pomoću java.io.FileReader, a zatim ih prikažete na zaslonu pomoću System.out.println (). Ako je datoteka napisana kodiranjem Cp866, izlaz će biti ispravan, s izuzetkom slova Š opet.

    Izravna pretvorba bajtova<->char.

    Ova je pogreška omiljena među stranim Java programerima. O tome se detaljno govori na početku opisa. Ako ikada pogledate izvore drugih ljudi, uvijek obratite pozornost na eksplicitnu pretvorbu tipa - (byte) ili (char). Grablje su često zakopane na takvim mjestima.

    Algoritam za pronalaženje problema s ruskim slovima

    Ako nemate pojma gdje u vašem programu može doći do gubitka ruskih slova, možete isprobati sljedeći test. Svaki se program može smatrati procesorom ulaznih podataka. Ruska slova su isti podaci, općenito prolaze tri faze obrade: čitaju se odnekud u memoriji programa (ulaz), obrađuju se unutar programa i prikazuju korisniku (izlaz). Kako biste odredili mjesto problema, umjesto podataka, trebali biste pokušati ušiti sljedeći testni redak u izvorni kod: "ABC \ u0410 \ u0411 \ u0412" i pokušati ga ispisati. Nakon toga pogledajte što imate:

    • Ako vidite "ABVABV", kompilacija izvora i izlaz ispravno rade za vas.
    • Ako umjesto prva tri slova vidite "??? ABC" (ili bilo koji drugi znak osim "ABC"), izlaz radi ispravno, ali je kompilacija izvora pogrešna - najvjerojatnije ključ za kodiranje nije navedeno.
    • Ako vidiš "??????" (ili bilo koji drugi simbol osim "ABC" umjesto druga tri slova), izlaz vam ne radi ispravno.

    Nakon što ste konfigurirali izlaz i kompilaciju, već možete lako shvatiti ulaz. Nakon postavljanja cijelog lanca, problemi bi trebali nestati.

    O uslužnom programu native2ascii

    Ovaj uslužni program dio je Sun JDK -a i dizajniran je za pretvaranje izvornog koda u ASCII format. On čita ulaznu datoteku pomoću navedenog kodiranja i ispisuje znakove u "\ uXXXX" formatu. Ako navedete -reverzni prekidač, tada će se izvršiti obrnuta pretvorba. Ovaj je program vrlo koristan za pretvaranje datoteka resursa (.properties) ili za obradu izvora ako sumnjate da se mogu sastaviti na računalima s regionalnim postavkama koje nisu ruske.

    Ako pokrenete program bez parametara, on radi sa standardnim unosom (stdin) i ne prikazuje natuknice kao drugi pomoćni programi. To dovodi do činjenice da mnogi ni ne shvaćaju da je potrebno navesti parametre (osim, možda, onih koji su našli snage i hrabrosti pogledati dokumentaciju :-). U međuvremenu, ovaj uslužni program za ispravan rad morate minimalno navesti kodiranje koje se koristi (s ključem -encoding). Ako se to ne učini, tada će se koristiti zadano kodiranje (file.encoding), koje se može ponešto razlikovati od očekivanog. Kao rezultat toga, nakon što ste primili pogrešne slovne kodove (zbog pogrešnog kodiranja), možete provesti puno vremena tražeći pogreške u apsolutno ispravnom kodu.

    O načinu pretvaranja znakova

    Mnogi ljudi pogrešno koriste ovu metodu, vjerojatno ne razumiju u potpunosti njezinu bit i ograničenja. Dizajniran je za vraćanje ispravnih slovnih kodova ako su pogrešno protumačeni. Bit metode je jednostavan: izvorni niz bajtova vraćen je iz primljenih netočnih znakova pomoću odgovarajuće kodne stranice. Zatim se iz ovog niza bajtova, pomoću već ispravne stranice, dobivaju normalni kodovi znakova. Primjer:

    String res = new String (src.getBytes ("ISO-8859-1"), "Cp1251");

    U korištenju ove tehnike može biti nekoliko problema. Na primjer, pogrešna stranica koristi se za oporavak ili se može promijeniti u nekim situacijama. Drugi problem može biti to što neke stranice izvode dvosmislenu konverziju bajtova<->char. Pogledajte, na primjer, opis greške prema broju.

    Stoga je vrijedno koristiti ovu metodu samo u najekstremnijem slučaju, kada ništa drugo ne pomaže, a imate jasnu predodžbu o tome gdje se događa netočna pretvorba znakova.

    Ruska slova i MS JVM

    Nejasno je iz kojih razloga, ali nedostaju sve datoteke za kodiranje ruskih slova, akrome Cp1251 (vjerojatno su na ovaj način pokušali smanjiti veličinu distribucije). Ako trebate druga kodiranja, na primjer, Cp866, tada morate dodati odgovarajuće klase u CLASSPATH. Štoviše, klase iz najnovijih verzija Sun JDK -a ne odgovaraju - Sun je dugo mijenjao svoju strukturu pa se najnovije verzije klasa ne podudaraju s Microsoftom (MS još uvijek ima strukturu iz JDK 1.1.4). Na Microsoft poslužitelju u načelu postoji cijeli niz dodatnih kodiranja, ali postoji datoteka veličine oko 3 metra, a njihov poslužitelj ne podržava ponovno preuzimanje :-). Uspio sam preuzeti ovu datoteku, prepakirao sam je u jar, možete je preuzeti odavde.

    Ako pišete aplet koji bi trebao raditi pod MS JVM -om i morali ste odnekud pročitati (na primjer, iz datoteke na poslužitelju) bajtove u ruskom kodiranju osim Cp1251 (na primjer, u Cp866), tada više nećete moći koristiti standardni mehanizam kodiranja - apletima je zabranjeno dodavanje klasa u sistemske pakete, što je u ovom slučaju paket sun.io. Postoje dva izlaza - ili ponovno dekodiranje datoteke na poslužitelju u Cp1251 (ili u UTF -8) ili, prije pretvaranja iz bajtova u Unicode, pretvaranje bajtova iz željenog kodiranja u Cp1251.

    Rusifikacija Jave za Linux

    Odmah ću reći - ne radim s Linuxom, a ovdje navedeni podaci dobiveni su od čitatelja ovog opisa. Ako nađete netočnost ili želite dodati - pišite mi.

    Postoje dva paralelna problema pri cirilisanju JVM -a na Linuxu:

    1. Problem s ćiriličnim izlazom u GUI komponentama
    2. Problem unosa ćirilice s tipkovnice (u X11)

    Problem povlačenja može se riješiti na ovaj način (ovaj je algoritam poslao Artemy E. Kapitula):

    1. Instalirajte normalne Windows NT / 200 ttf fontove u X11. Preporučio bih Arial, Times New Roman, Courier New, Verdana i Tahoma - i bolje ih je povezati ne putem poslužitelja fontova, već kao direktorij s datotekama.
    2. Dodajte sljedeću datoteku font.properties.ru u direktorij $ JAVA_HOME / jre / lib

    Ulazni problem riješen je otprilike na sljedeći način (ovaj je algoritam poslao Mihail Ivanov):

    Postavljanje unosa ruskih slova u sljedećoj konfiguraciji:

    • Mandrake Linux 7.1
    • XFree86 3.3.6
    • IBM Java 1.3.0 (izdanje)

    Problem:

    IBM Java 1.3 ne dopušta unos ruskih slova (vidljivi su kao krokodili), unatoč činjenici da su vidljivi na naljepnicama i u izbornicima.

    pomoću XIM-a (-> xkb) u AWT-u. (ovo nije loše samo po sebi, samo se s njima treba pažljivo rukovati + nekim se alatima xkb to ne sviđa).

    Konfigurirajte xkb (i jezik (xkb bez lokalizacije NE RADI))

    Postupak:

    1. lokalizacija je izložena (negdje poput / etc / profile ili ~ / .bash_profile)
      izvoz LANG = ru_RU.KOI8-R izvoz LC_ALL = ru_RU.KOI8-R
    2. urediti (ako već nije učinjeno) / etc / X11 / XF86Config. Odjeljak Tipkovnica trebao bi sadržavati nešto poput ovoga:
      XkbKeycodes "xfree86" XkbTypes "zadano" XkbCompat "zadano" XkbSymbols "ru" XkbGeometry "pc" XkbRules "xfree86" XkbModel "pc101" XkbLayout "ru" XkbOptions "ohp# shift_tog prekidač
      napomena: ova postavka xkb nije kompatibilna s xrus -om (i drugima se sviđa poput kikbd -a) pa ćete se morati oprostiti od njih.
    3. X se ponovno pokreću. Morate provjeriti radi li sve (poput ruskih slova u terminalu i aplikacijama)
    4. font.properties.ru -> $ JAVA_HOME / jre / lib
    5. fontovi.dir -> $ JAVA_HOME / jre / lib / fontovi
    6. cd $ JAVA_HOME / jre / lib / fontovi; rm fontovi.scale; ln -s fontovi.dir fontovi.razmjer

    Sada bi bez problema trebalo unijeti i prikazati ruska slova.

Ako primijetite netočnost u opisu ili želite dodati, onda mi pišite o tome, a vaše će se ime također pojaviti na ovom popisu. :-)

U prilogu je potpuna podrška za .htaccess direktive ...

Obnova domene 199-00 rubalja

Kodiranje je tablica simbola, gdje je svakom slovu abecede (kao i brojevima i posebnim znakovima) dodijeljen jedinstveni broj - kod simbola.

Samo je polovica tablice standardizirana, tzv. ASCII kôd - prvih 128 znakova koji uključuju slova latinične abecede. I s njima nikad nema problema. Druga polovica tablice (a u njoj je ukupno 256 simbola - prema broju stanja koja jedan bajt može uzeti) navedena je pod nacionalnim simbolima, a u svakoj je zemlji ovaj dio drugačiji. Ali samo su u Rusiji uspjeli smisliti čak 5 različitih kodiranja. Izraz "različit" znači da isti simbol odgovara drugom digitalnom kodu. Oni. ako pogrešno odredimo kodiranje teksta, tada će nam pozornost biti posvećena apsolutno nečitljivom tekstu.

Kodiranja su se pojavila povijesno. Zvalo se prvo široko korišteno rusko kodiranje KOI-8... Izumljen je kada je UNIX sustav prilagođen ruskom jeziku. Bilo je to sedamdesetih godina - prije pojave osobnih računala. I do sada se u UNIX -u to smatra glavnim kodiranjem.

Tada su se pojavila prva osobna računala i počeo je trijumfalni marš DOS -a. Umjesto da koristi već izmišljeno kodiranje, Microsoft je odlučio napraviti svoje, nespojivo s bilo čim. Ovako se pojavio DOS kodiranje(ili 866 kodna stranica). Usput, uveo je posebne znakove za crtanje okvira, što se naširoko koristilo u programima napisanim pod DOS -om. Na primjer, u istom Norton Commanderu.

Macintosh računala razvijala su se paralelno s onima kompatibilnim s IBM-om. Unatoč činjenici da je njihov udio u Rusiji vrlo mali, ipak je postojala potreba za rusifikacijom i, naravno, izmišljeno je drugo kodiranje - MAC.

Vrijeme je prolazilo, a 1990. Microsoft je na svjetlo dana iznio prve uspješne Verzija sustava Windows 3.0-3.11. Uz to i podršku nacionalnim jezicima. I opet je učinjen isti trik kao i kod DOS -a. Iz nekog nepoznatog razloga, nisu podržali nijedan od prethodno postojećih (kao ni OS / 2, koji je prihvatio DOS kodiranje kao standard), ali su predložili novi Win kodiranje(ili kodna stranica 1251 ). De facto, postala je najrasprostranjenija u Rusiji.

I, konačno, peta opcija kodiranja više nije povezana s određenom tvrtkom, već s pokušajima standardizacije kodiranja na razini cijelog planeta. To je učinila ISO, međunarodna organizacija za standarde. I pogodite što su učinili s ruskim jezikom? Umjesto da su bilo što od gore navedenog zamijenili za "standardni ruski", smislili su još jedan (!) I nazvali ga dugo probavljivom kombinacijom ISO-8859-5... Naravno, i to se pokazalo nespojivim s bilo čim. I trenutno se ovo kodiranje praktički nigdje ne koristi. Čini se da se koristi samo u Oracle bazi podataka. Barem nikad nisam vidio tekst u ovom kodiranju. Međutim, podržan je u svim preglednicima.

Sada radimo na stvaranju novog univerzalnog kodiranja ( UNICODE), u kojoj se pretpostavlja da će svi jezici svijeta strpati u jednu tablicu kodova. Tada definitivno neće biti problema. Za to su dodijeljena 2 bajta za svaki znak. Tako se maksimalni broj znakova u tablici proširio na 65535. No, ostalo je još previše vremena prije nego svi pređu na UNICODE.


Ovdje smo malo odstupili i razmotrili meta oznaku - Content -Type za cjelovitu percepciju.

Meta oznake koriste se za opis svojstava HTML dokumenta i moraju se nalaziti unutar oznake HEAD. Meta oznake poput NAME sadrže tekstualne podatke o dokumentu, njegovom autoru i neke preporuke za tražilice. Na primjer: Roboti, opis, ključne riječi, autor, autorska prava.

Meta oznake tipa HTTP-EQUIV utječu na formiranje zaglavlja dokumenta i određuju način njegove obrade.

Meta oznaka - Vrsta sadržaja - Odgovoran za navođenje vrste dokumenta i kodiranje znakova.

Meta oznaku Content-Type potrebno je koristiti samo uzimajući u obzir neke nijanse:

    Prvo, kodiranje znakova u tekstu mora odgovarati kodiranju navedenom u oznaci.

    Drugo, poslužitelj ne bi trebao mijenjati kodiranje teksta prilikom obrade zahtjeva preglednika.

    Treće, ako poslužitelj promijeni kodiranje teksta, mora ispraviti ili ukloniti meta oznaku Content-Type.

Nepoštivanje ovih zahtjeva može dovesti do sljedećeg: web poslužitelj će automatski otkriti kodiranje klijentovog zahtjeva i dati kodiranu stranicu web pregledniku. Preglednik će čitati dokument prema meta oznaci Content-Type. A ako se kodiranja ne podudaraju, tada se dokument može pročitati tek nakon niza zamršenih manipulacija. To se posebno odnosi na starije preglednike.

Pažnja! Meta oznaka vrste sadržaja vrlo često se ubacuje Generatori HTML -a kodirati.

Najčešći tipovi kodiranja su:

    Windows -1251 - ćirilica (Windows).

    KOI8-r-ćirilica (KOI8-R)

    cp866 - ćirilica (DOS).

    Windows -1252 - Zapadna Europa (Windows).

    Windows -1250 - Srednja Europa (Windows).

Sigurno svi znaju meta oznaku -

V. ovaj materijal korišteni odlomci iz članka sa web stranice http://cherry-design.ru/

Nedavno objavljene domene s PR -om i TIC -om:

Usluga http://reg.ru - najveći hosting i registrator domena, omogućuje vam da se prijavite za registraciju naziva domene, koju je nedavno objavio prethodni administrator. Oslobođene domene često imaju visoke stope TIC -a i PR -a te bi ih moglo biti zanimljivo kupiti.

Oslobođene domene .RU c TIC:
Besplatne premium domene:

Količina informacija: 7659 bajtova

Povijesno je 7 bitova dodijeljeno za predstavljanje ispisanih znakova (kodiranje teksta) na prvim računalima. 2 7 = 128. Taj je iznos bio sasvim dovoljan za kodiranje svih malih slova i velika slova Latinska abeceda, deset brojeva i razni znakovi i zagrade. To je upravo ta 7-bitna tablica ASCII znakovi(Američki standardni kôd za razmjenu informacija), detaljne informacije koje možete dobiti naredbom man ascii operacijski sustav Linux.

Kad je postalo potrebno kodirati nacionalna pisma, 128 znakova nije bilo dovoljno. Odlučeno je da se pređe na kodiranje pomoću 8 bita (tj. Jedan bajt). Kao rezultat toga, broj znakova koji se mogu kodirati na ovaj način postao je jednak 2 8 = 256. Istodobno, simboli nacionalnih abeceda nalazili su se u drugoj polovici tablice kodova, odnosno sadržavali su jedinicu u najznačajnijem bitu bajta dodijeljenom za kodiranje znaka. Tako se pojavio standard ISO 8859 koji sadrži mnoštvo kodiranja za najčešće jezike.

Među njima je bila jedna od prvih tablica za kodiranje ruskih slova - ISO 8859-5(upotrijebite naredbu man iso_8859_1 da biste dobili kodove za ruska slova u ovoj tablici).

Prijenos zadataka tekstualne informacije mreža je bila prisiljena razviti još jedno kodiranje za ruska slova, tzv Koi8-R(kod za prikaz informacija je 8-bitni, rusificiran). Razmotrimo situaciju kada se pismo koje sadrži ruski tekst šalje putem e-mail... Dogodilo se da je u procesu putovanja kroz mreže pismo obradilo program koji je radio sa 7-bitnim kodiranjem i nulirao osmi bit. Kao rezultat ove transformacije, kôd znakova smanjen je za 128, pretvarajući se u kôd znakova latinske abecede. Bilo je potrebno povećati stabilnost prenesenih tekstualnih informacija na nuliranje 8 bita.

Srećom, značajan broj ćiriličnih slova ima glasovne podudarnosti u latinici. Na primjer, F i F, P i R. Postoji nekoliko slova koja se podudaraju čak i u obrisima. Raspoređivanje ruskih slova tablica kodova na način da njihov kod premašuje kôd sličan latinski do broja 128, postigli su da je gubitak 8. bita preokrenuo tekst, iako se sastojao od jedne latinice, ali ga je i dalje razumio korisnik koji govori ruski.

Budući da su od svih tada raširenih operacijskih sustava najprikladniji način rada s mrežom posjedovali različiti klonovi operativnih sustava Unix sustavi tada je to kodiranje postalo de facto standard u tim sustavima. To je još uvijek slučaj u Linuxu. I upravo se to kodiranje najčešće koristi za razmjenu pošte i vijesti na Internetu.

Onda je došlo doba osobna računala i operacijski sustav MS DOS. Kako se ispostavilo, kodiranje Koi8-R nije joj odgovaralo (baš kao ni ISO 8859-5), u njezinoj tablici neka su ruska slova bila na onim mjestima za koja su mnogi programi pretpostavljali da su ispunjeni pseudografikama (vodoravne i okomite crte, kutovi itd.) .). itd.). Stoga je izmišljeno još jedno ćirilično kodiranje u čijoj tablici su ruska slova "tekla oko" grafičkih simbola sa svih strana. Zove se ovo kodiranje alternativa(alt) jer je to bila alternativa službenom standardu, ISO-8859-5 kodiranje. Neosporna prednost ovog kodiranja je ta što su ruska slova u njemu poredana abecednim redom.

Nakon pojavljivanja sustava Windows iz Microsofta, pokazalo se da mu alternativno kodiranje iz nekog razloga nije prikladno. Ponovno premještanje ruskih slova u tablicu (postojala je prilika - uostalom, pseudo -grafika u sustavu Windows nije potrebna), dobili smo kodiranje Windows 1251(Win-1251).

No, računalne tehnologije se stalno poboljšavaju i trenutno sve veći broj programa počinje podržavati standard Unicode koji vam omogućuje kodiranje gotovo svih jezika i dijalekata stanovnika Zemlje.

Dakle, u različitim operativnim sustavima prednost se daje različitim kodiranjima. Kako bi se omogućilo čitanje i uređivanje teksta upisanog u drugom kodiranju, koriste se ruski programi za transkodiranje teksta. Neki uređivači teksta sadrže ugrađene transkodere koji vam omogućuju čitanje teksta u različitim kodiranjima (Word itd.). Za pretvaranje datoteka koristit ćemo niz pomoćnih programa u Linuxu čija je svrha jasna iz naziva: alt2koi, win2koi, koi2win, alt2win, win2alt, koi2alt (odakle, gdje, broj 2 (dva) je sličan u zvuk prema prijedlogu do, koji označava smjer). Ove naredbe imaju istu sintaksu: command<входной_файл >izlazna datoteka.

Primjer

Prekodirajmo tekst otkucan u Edit editoru u okruženju MS DOS u kodiranje Koi8-R. Da biste to učinili, pokrenite naredbu

alt2koi file1.txt> filenew

Budući da su sažeci podataka različito kodirani u MS DOS -u i Linuxu, također se preporučuje izvršavanje naredbe "fromdos":

fromdos filenew> file2.txt

Obrnuta naredba naziva se "todos" i ima istu sintaksu.

Primjer

Sortirajmo datoteku List.txt koja sadrži popis prezimena i pripremljenu u kodiranju Koi8-R abecednim redom. Upotrijebimo naredbu sort koja sortira tekstualnu datoteku prema uzlaznom ili silaznom redoslijedu kodova znakova. Ako ga odmah primijenite, onda, na primjer, pismo V. bit će na kraju popisa, slično odgovarajućem slovu latinične abecede V.... Sjećajući se da su u alternativnom kodiranju ruska slova raspoređena strogo po abecedi, izvršit ćemo niz operacija: prekodirati tekst u alternativno kodiranje, sortirati ga i vratiti u kodiranje Koi8-R. Pomoću naredbenog cjevovoda dobivamo

koi2alt List.txt | sortiraj | alt2koi> List_Sort.txt

U modernim distribucijama Linuxa mnogi su problemi povezani s lokalizacija softver... Konkretno, uslužni program za sortiranje sada uzima u obzir posebnosti koi8-R kodiranja, a za sortiranje datoteke abecednim redom samo pokrenite naredbu

Kodiranja

Kad sam tek počeo programirati na C-u, moj prvi program (osim HelloWorld-a) bio je program za pretvaranje tekstualnih datoteka iz glavnog GOST kodiranja (sjećate li se ovog? :-) u alternativni. Bilo je to davne 1991. godine. Od tada se mnogo toga promijenilo, ali nažalost takvi programi nisu izgubili na važnosti u posljednjih 10 godina. Previše je podataka već prikupljeno u različitim kodiranjima i koristi se previše programa koji mogu raditi samo s jednim. Za ruski jezik postoji najmanje desetak različitih kodiranja, što problem čini još zbunjujućim.

Odakle su došla ta kodiranja i čemu služe? Računala po svojoj prirodi mogu raditi samo s brojevima. Za spremanje slova u memoriju računala potrebno je svakom slovu dodijeliti određeni broj (otprilike isti princip je korišten prije pojavljivanja računala - zapamtite isti Morzeov kod). Štoviše, broj je poželjno manji - što je manje binarnih znamenki u pitanju, to se memorija može učinkovitije koristiti. Ova korespondencija između skupa znakova i brojeva zapravo je kodiranje. Želja da se pod svaku cijenu sačuva memorija, kao i nejedinstvo različitih skupina informatičara doveli su do trenutnog stanja. Najčešća metoda kodiranja sada je korištenje jednog bajta (8 bita) za jedan znak, što određuje ukupan broj znakova u 256. Skup prvih 128 znakova je standardiziran (skup ASCII) i isti je u svim uobičajenim kodiranjima (ona kodiranja gdje već nije tako praktički izvan upotrebe). Anglikanska slova i simboli interpunkcije nalaze se u ovom rasponu, što određuje njihovu nevjerojatnu preživljavanje u računalnim sustavima :-). Drugi jezici nisu tako sretni - svi se moraju zgrnuti u preostalih 128 brojeva.

Unicode

Krajem 1980 -ih mnogi su shvatili potrebu stvaranja jedinstvenog standarda za kodiranje znakova, što je dovelo do pojave Unicodea. Unicode je pokušaj da se jednom zauvijek popravi određeni broj za određeni znak. Jasno je da se 256 znakova ovdje neće uklopiti sa svom željom. Dugo se činilo da bi 2 bajta (65536 znakova) trebala biti dovoljna. Ali ne - najnovija verzija Unicode standarda (3.1) već definira 94.140 znakova. Za takav broj znakova vjerojatno već morate koristiti 4 bajta (4294967296 znakova). Možda dosta za neko vrijeme ... :-)

Skup znakova Unicode uključuje sve vrste slova sa svim vrstama crtica i papendyulki, grčkih, matematičkih, hijeroglifa, pseudo-grafičkih simbola itd. Itd. Uključujući naše omiljene ćirilične znakove (raspon vrijednosti je 0x0400-0x04ff) . Dakle, s ove strane nema diskriminacije.

Ako vas zanimaju posebni kodovi znakova, prikladno je koristiti program "Karta znakova" iz WinNT -a za njihov pregled. Na primjer, ovdje je raspon ćirilice:

Ako imate drugi OS ili ste zainteresirani za službeno tumačenje, tada se potpuni grafikoni mogu pronaći na službenoj web stranici Unicode (http://www.unicode.org/charts/web.html).

Vrste znakova i bajtova

Java ima zasebnu vrstu podataka char od 2 bajta za znakove. To često stvara zabunu u glavama početnika (osobito ako su prethodno programirali na drugim jezicima, poput C / C ++). To je zato što većina drugih jezika koristi 1-bajtne vrste podataka za obradu znakova. Na primjer, u C / C ++ tip char se u većini slučajeva koristi i za rukovanje znakovima i za rukovanje bajtovima - nema razdvajanja. Java ima svoj tip bajtova - tip bajtova. Dakle, char temeljen na C odgovara Java bajtu, a Java char iz svijeta C najbliži je tipu wchar_t. Potrebno je jasno razdvojiti pojmove znakova i bajtova - u protivnom su nesporazumi i problemi zajamčeni.

Java koristi standard Unicode za kodiranje znakova gotovo od svog početka. Funkcije Java knjižnice očekuju da će vidjeti Unicode znakove u varijablama char. U načelu, naravno, tamo možete ubaciti bilo što - brojevi su brojevi, procesor će izdržati sve, ali za svaku obradu, funkcije knjižnice će djelovati pod pretpostavkom da su dobile Unicode kodiranje. Stoga možete sa sigurnošću pretpostaviti da je kodiranje znakova fiksno. Ali ovo je unutar JVM -a. Kada se podaci čitaju izvana ili prosljeđuju izvana, tada se mogu predstaviti samo jednom vrstom - vrstom bajta. Svi ostali tipovi izrađeni su od bajtova, ovisno o formatu podataka koji se koristi. Ovdje kodiranje dolazi u obzir - u Javi je to samo format podataka za prijenos znakova, koji se koristi za formiranje podataka tipa char. Za svaku kodnu stranicu u knjižnici postoje 2 razreda pretvorbe (ByteToChar i CharToByte). Ove klase su u paketu sun.io. Ako pri pretvaranju iz char u bajt nije pronađen odgovarajući znak, zamjenjuje se znakom?

Usput, ove datoteke kodnih stranica u nekim ranijim verzijama JDK 1.1 sadrže greške koje uzrokuju pogreške pretvorbe ili čak iznimke za vrijeme izvođenja. Na primjer, ovo se odnosi na kodiranje KOI8_R. Najbolje što trebate učiniti je promijeniti verziju na kasniju. Na temelju Sunčevog opisa, većina ovih problema riješena je u JDK 1.1.6.

Prije JDK 1.4, skup dostupnih kodiranja odredio je samo dobavljač JDK. Počevši od 1.4, pojavio se novi API (paket java.nio.charset), s kojim već možete stvoriti vlastito kodiranje (na primjer, podržati rijetko korišteno, ali užasno potrebno za vas).

Klasa niza

U većini slučajeva Java koristi objekt tipa java.lang.String za predstavljanje nizova. Ovo je redovna klasa koja interno pohranjuje niz znakova (char) i koja sadrži mnoge korisne metode za upravljanje znakovima. Najzanimljiviji su konstruktori s nizom bajtova kao prvim parametrom i metode getBytes (). Pomoću ovih metoda možete izvesti pretvorbe iz nizova bajtova u nizove i obrnuto. Kako bi se odredilo koje će se kodiranje koristiti u isto vrijeme, ove metode imaju parametar niza koji postavlja njegovo ime. Na primjer, evo kako možete pretvoriti bajte iz KOI-8 u Windows-1251:

// Podaci kodirani KOI-8 bajt koi8Data = ...; // Pretvori iz KOI-8 u Unicode String string = new String (koi8Data, "KOI8_R"); // Pretvorba iz Unicodea u Windows-1251 bajt winData = string.getBytes ("Cp1251");

Popis 8-bitnih kodiranja dostupnih u modernim JDK-ovima i koji podržavaju ruska slova nalazi se ispod, u odjeljku.

Budući da je kodiranje format podataka za znakove, osim poznatih 8-bitnih kodiranja u Javi, postoje i višekodirana kodiranja na jednakim osnovama. To uključuje UTF-8, UTF-16, Unicode itd. Na primjer, ovako možete dobiti bajtove u formatu UnicodeLittleUnmarked (16-bitno kodiranje Unicode, prvo niskobajtno, bez znaka za poredak bajtova):

// Pretvoriti iz Unicode u Unicode data byte = string.getBytes ("UnicodeLittleUnmarked");

Lako je pogriješiti s takvim konverzijama - ako kodiranje podataka bajta ne odgovara navedenom parametru pri pretvaranju iz bajta u char, tada se prepisivanje neće izvršiti ispravno. Ponekad nakon toga možete izvući ispravne znakove, no češće će se dio podataka nepovratno izgubiti.

U stvarnom programu nije uvijek zgodno navesti kodnu stranicu izričito (iako je pouzdanija). Za to je uvedeno zadano kodiranje. Prema zadanim postavkama, to ovisi o sustavu i njegovim postavkama (za ruski Windows, kodiranje Cp1251 je usvojeno), a u starim JDK -ovima može se promijeniti postavljanjem datoteke svojstava sustava.kodiranje. U JDK 1.3, promjena ove postavke ponekad funkcionira, ponekad ne. To je uzrokovano sljedećim: u početku se datotečno kodiranje postavlja prema regionalnim postavkama računala. Zadana referenca kodiranja interno se pamti tijekom prve pretvorbe. U ovom slučaju koristi se file.encoding, no do ove se konverzije dolazi čak i prije korištenja argumenata za pokretanje JVM -a (zapravo, prilikom njihovog raščlanjivanja). Zapravo, kaže Sun, ovo svojstvo odražava kodiranje sustava i ne treba ga mijenjati u naredbenom retku (vidi, na primjer, komentare na BugID). Međutim, u JDK 1.4 Beta 2, promjena ove postavke ponovno je imala učinka. Što je ovo, svjesna promjena ili nuspojava koja može opet nestati - Sunčeve ovce još nisu dale jasan odgovor.

Ovo kodiranje se koristi kada naziv stranice nije izričito naveden. To uvijek treba zapamtiti - Java neće pokušati predvidjeti kodiranje bajtova koje proslijedite za stvaranje Stringa (također neće moći pročitati vaša razmišljanja o tome :-). Koristi samo trenutno zadano kodiranje. Jer ova je postavka ista za sve transformacije, ponekad možete naići na probleme.

Za pretvaranje iz bajtova u znakove i obrnuto koristite samo ovim metodama. U većini slučajeva ne može se koristiti jednostavna pretvorba tipa - kodiranje znakova neće se uzeti u obzir. Na primjer, jedna od najčešćih grešaka je čitanje podataka po bajtovima pomoću metode read () iz InputStream-a, a zatim dobivena vrijednost prebacivanje na tip char:

Ulazni tok je = ..; int b; StringBuffer sb = novi StringBuffer (); while ((b = is.read ())! = - 1) (sb.append ((char) b); // <- так делать нельзя ) Niz s = sb.toString ();

Obratite pažnju na tipkanje - "(char) b". Vrijednosti bajtova jednostavno se kopiraju u char umjesto ponovnog kodiranja (raspon vrijednosti je 0-0xFF, a ne onaj gdje je ćirilica). Ovo kopiranje odgovara kodiranju ISO-8859-1 (koje jedan na jedan odgovara prvim 256 Unicode vrijednostima), što znači da možemo pretpostaviti da ga ovaj kôd jednostavno koristi (umjesto onog u kojem su znakovi u izvorni podaci su zapravo kodirani). Ako pokušate prikazati primljenu vrijednost, na zaslonu će se pojaviti pitanja ili krakozjabilno. Na primjer, pri čitanju niza "ABC" u kodiranju sustava Windows može se lako prikazati nešto poput ovoga: "AV". Ovu vrstu koda često pišu programeri na Zapadu - radi s engleskim slovima, i u redu. Popravljanje ovog koda je jednostavno - samo trebate zamijeniti StringBuffer s ByteArrayOutputStream:

Ulazni tok je = ..; int b; ByteArrayOutputStream baos = novi ByteArrayOutputStream (); while ((b = is.read ())! = - 1) (baos.write (b);) // Pretvorba bajtova u niz pomoću zadanog kodiranja Niz s = baos.toString (); // Ako vam je potrebno posebno kodiranje, samo ga navedite prilikom pozivanja toString (): // // s = baos.toString ("Cp1251");
Za više informacija o uobičajenim pogreškama pogledajte odjeljak.

8-bitno kodiranje ruskih slova

Evo glavnih 8-bitnih kodiranja ruskih slova koja su postala široko rasprostranjena:

Osim glavnog naziva, mogu se koristiti i sinonimi. Njihov skup može se razlikovati u različitim verzijama JDK -a. Evo popisa iz JDK 1.3.1:

  • CP1251:
    • Windows-1251
  • CP866:
    • IBM866
    • IBM-866
    • CP866
    • CSIBM866
  • KOI8_R:
    • KOI8-R
    • CSKOI8R
  • ISO8859_5:
    • ISO8859-5
    • ISO-8859-5
    • ISO_8859-5
    • ISO_8859-5: 1988
    • ISO-IR-144
    • 8859_5
    • Ćirilica
    • CSISOLatinCirilica
    • IBM915
    • IBM-915
    • Cp915

Štoviše, sinonimi, za razliku od glavnog naziva, ne razlikuju velika i mala slova - to je značajka implementacije.

Vrijedi napomenuti da ova kodiranja možda nisu dostupna na nekim JVM -ovima. Na primjer, možete preuzeti dvije različite verzije JRE -a sa Sun -ove web stranice, američku i međunarodnu. U američkoj verziji postoji samo minimum-ISO-8859-1, ASCII, Cp1252, UTF8, UTF16 i nekoliko varijacija dvobajtnog Unicodea. Sve ostalo dostupno je samo u međunarodnoj verziji. Ponekad zbog toga možete naletjeti na grablje s pokretanjem programa, čak i ako ne trebaju ruska slova. Tipična greška koja se događa dok to radite:

Došlo je do pogreške tijekom inicijalizacije VM java / lang / ClassNotFoundException: sun / io / ByteToCharCp1251

Nastaje, kako nije teško pogoditi, zbog činjenice da JVM, na temelju ruskih regionalnih postavki, pokušava postaviti zadano kodiranje u Cp1251, ali budući da klasa takve podrške nema u američkoj verziji, prirodno se prekida.

Datoteke i podatkovni tokovi

Baš kao što su bajtovi konceptualno odvojeni od znakova, Java razlikuje tokove bajtova i znakove. Rad s bajtovima predstavljen je klasama koje izravno ili neizravno nasljeđuju klase InputStream ili OutputStream (plus jedinstvena klasa RandomAccessFile). Rad sa simbolima predstavlja slatki par razreda Čitatelj / Pisac (i njihovi potomci, naravno).

Nizovi bajtova koriste se za čitanje / pisanje nepreobraćenih bajtova. Ako znate da bajtovi predstavljaju samo znakove u određenom kodiranju, možete koristiti posebne klase pretvarača InputStreamReader i OutputStreamWriter da biste dobili niz znakova i izravno radili s njima. To je obično korisno za datoteke s običnim tekstom ili pri radu s mnogim internetskim mrežnim protokolima. U ovom slučaju kodiranje znakova je navedeno u konstruktoru klase pretvarača. Primjer:

// Unicode niz String string = "..."; // Zapišite niz u tekstualnu datoteku u kodiranju Cp866 PrintWriter pw = novi PrintWriter // klasa s metodama za pisanje nizova(novi OutputStreamWriter // klasa-pretvarač(novi FileOutputStream ("file.txt"), "Cp866"); pw.println (niz); // zapisujemo redak u datoteku pw.close ();

Ako tok može sadržavati podatke u različitim kodiranjima ili su znakovi pomiješani s drugim binarnim podacima, onda je bolje čitati i pisati nizove bajtova (bajtova), a za pretvorbu koristiti već spomenute metode klase String. Primjer:

// Unicode niz String string = "..."; // Zapišite niz u tekstualnu datoteku u dva kodiranja (Cp866 i Cp1251) OutputStream os = novi FileOutputStream ("file.txt"); // klasa za upisivanje bajtova u datoteku // Zapišite niz u kodiranju Cp866 os.write (string.getBytes ("Cp866")); // Zapišite niz u kodiranju Cp1251 os.write (string.getBytes ("Cp1251")); os.close ();

Konzola u Javi tradicionalno je predstavljena tokovima, ali, nažalost, ne znakovima, već bajtovima. Činjenica je da su se znakovni tokovi pojavili samo u JDK 1.1 (zajedno s cijelim mehanizmom kodiranja), a pristup konzoli I / O je dizajniran u JDK 1.0, što je dovelo do pojave čudaka u obliku klase PrintStream. Ova se klasa koristi u varijablama System.out i System.err, koje zapravo daju pristup izlazu na konzolu. Po svemu sudeći, ovo je niz bajtova, ali s hrpom metoda za pisanje nizova. Kad u njega upišete niz, on se pretvara u bajte pomoću zadanog kodiranja, što je obično neprihvatljivo u slučaju sustava Windows - zadano kodiranje bit će Cp1251 (Ansi), a za prozor konzole obično morate koristiti Cp866 ( OEM). Ova je pogreška registrirana još 97. godine (), ali čini se da Sun-ovce ne žure sa ispravljanjem. Budući da ne postoji metoda za postavljanje kodiranja u PrintStreamu, za rješavanje ovog problema možete zamijeniti standardnu ​​klasu vlastitom pomoću metoda System.setOut () i System.setErr (). Na primjer, evo uobičajenog početka u mojim programima:

... javni statički void main (String args) ( // Postavite izlaz konzolnih poruka u željenom kodiranju pokušajte (String consoleEnc = System.getProperty ("console.encoding", "Cp866"); System.setOut (novi CodepagePrintStream (System.out, consoleEnc)); System.setErr (novi CodepagePrintStream (System.err, consoleEnc)); ) catch (UnsupportedEncodingException e) (System.out.println ("Nije moguće postaviti kodnu stranicu konzole:" + e);) ...

Izvore klase CodepagePrintStream možete pronaći na ovoj web stranici: CodepagePrintStream.java.

Ako sami konstruirate format podataka, preporučujem da upotrijebite jedno od višebajtnih kodiranja. Najprikladniji format obično je UTF8 - prvih 128 vrijednosti (ASCII) u njemu kodirano je u jednom bajtu, što često može značajno smanjiti ukupnu količinu podataka (nije uzalud to kodiranje uzeto kao osnova u XML svijet). No, UTF8 ima jedan nedostatak - broj potrebnih bajtova ovisi o kodu znaka. Tamo gdje je to kritično, možete koristiti jedan od dvobajtnih formata Unicode (UnicodeBig ili UnicodeLittle).

Baza podataka

Za ispravno čitanje znakova iz baze podataka obično je dovoljno reći JDBC pogonitelju potrebno kodiranje znakova u bazi podataka. Kako točno ovisi o konkretnom vozaču. Danas mnogi vozači već podržavaju ovu postavku, za razliku od nedavne prošlosti. Evo nekoliko primjera za koje znam.

JDBC-ODBC most

Ovo je jedan od najčešće korištenih upravljačkih programa. Most iz JDK 1.2 i starije može se jednostavno konfigurirati na željeno kodiranje. To se postiže dodavanjem dodatnog svojstva charSet u skup parametara proslijeđenih za otvaranje veze s bazom. Zadana vrijednost je file.encoding. Ovo se radi otprilike ovako:

// Uspostavite vezu

Oracle 8.0.5 JDBC-OCI upravljački program za Linux

Prilikom primanja podataka iz baze podataka, ovaj upravljački program određuje "svoje" kodiranje pomoću varijable okruženja NLS_LANG. Ako se ova varijabla ne pronađe, pretpostavlja se da je kodiranje ISO-8859-1. Trik je u tome što bi NLS_LANG trebala biti varijabla okruženja (postavljena naredbom set), a ne svojstvo Java sustava (poput file.encoding). U slučaju korištenja pogonitelja unutar stroja servera Apache + Jserv, varijablu okruženja možete postaviti u datoteci jserv.properties:

omot.env = NLS_LANG = Američka_Amerika.CL8KOI8R
Informaciju o tome poslao je Sergej Bezrukov, na čemu mu posebno zahvaljuje.

JDBC upravljački program za rad s DBF -om (zyh.sql.dbf.DBFDriver)

Ovaj je vozač tek nedavno naučio raditi s ruskim slovima. Iako je putem getPropertyInfo () izvijestio da razumije svojstvo charSet, to je fikcija (barem u verziji od 30.7.2001.). U stvarnosti, kodiranje možete prilagoditi postavljanjem svojstva CODEPAGEID. Za ruske znakove dostupne su dvije vrijednosti - "66" za Cp866 i "C9" za Cp1251. Primjer:

// Osnovni parametri povezivanja Svojstva connInfo = nova svojstva (); connInfo.put ("CODEPAGEID", "66"); // Cp866 kodiranje // Uspostavite vezu Veza db = DriverManager.getConnection ("jdbc: DBF: / C: / MyDBFFiles", connInfo);
Ako imate DBF datoteke FoxPro formata, onda one imaju svoje specifičnosti. Činjenica je da FoxPro sprema u zaglavlje datoteke ID kodne stranice (bajt s pomakom 0x1D), koji je korišten za stvaranje DBF -a. Prilikom otvaranja tablice, upravljački program koristi vrijednost iz zaglavlja, a ne parametar "CODEPAGEID" (parametar se u ovom slučaju koristi samo pri stvaranju novih tablica). U skladu s tim, kako bi sve radilo ispravno, DBF datoteka mora biti stvorena s ispravnim kodiranjem - inače će doći do problema.

MySQL (org.gjt.mm.mysql.Driver)

S ovim upravljačkim programom sve je također prilično jednostavno:

// Osnovni parametri povezivanja Svojstva connInfo = nove osobine (); connInfo.put ("korisnik", korisnik); connInfo.put ("lozinka", prolaz); connInfo.put ("useUnicode", "true"); connInfo.put ("characterEncoding", "KOI8_R"); Veza conn = DriverManager.getConnection (dbURL, rekviziti);

InterBase (interbase.interclient.Driver)

Za ovaj upravljački program radi parametar "charSet":
// Osnovni parametri povezivanja Svojstva connInfo = nova svojstva (); connInfo.put ("korisnik", korisničko ime); connInfo.put ("lozinka", lozinka); connInfo.put ("charSet", "Cp1251"); // Uspostavite vezu Veza db = DriverManager.getConnection (dataurl, connInfo);

Međutim, ne zaboravite navesti kodiranje znakova pri stvaranju baze podataka i tablica. Za ruski jezik možete koristiti vrijednosti "UNICODE_FSS" ili "WIN1251". Primjer:

IZRADI BAZU PODATAKA ′ E: ProjectHoldingDataBaseHOLDING.GDB ′ PAGE_SIZE 4096 ZNAČAJNI NIZ ZNAKA UNICODE_FSS; CREATE TABLE RUSSIAN_WORD ("NAME1" VARCHAR (40) CHARACTER SET UNICODE_FSS NOT NULL, "NAME2" VARCHAR (40) CHARACTER SET WIN1251 NOT NULL, PRIMARY KEY ("NAME1"));

Postoji greška u verziji 2.01 InterClienta - klase resursa s porukama za ruski jezik tamo nisu pravilno sastavljene. Najvjerojatnije su programeri jednostavno zaboravili navesti izvorno kodiranje pri prevođenju. Postoje dva načina za ispravljanje ove pogreške:

  • Koristite interclient-core.jar umjesto interclient.jar. Istodobno, jednostavno neće biti ruskih resursa, a engleski će se automatski pokupiti.
  • Ponovno kompajlirajte datoteke u uobičajeni Unicode. Raščlanjivanje datoteka klasa nezahvalan je zadatak, pa je bolje koristiti JAD. Nažalost, JAD, ako naiđe na znakove iz skupa ISO-8859-1, emitira ih u 8-znamenkasti kodiranju, tako da nećete moći koristiti standardni native2ascii koder-morate napisati vlastiti (Decode program). Ako se ne želite zamarati tim problemima, možete uzeti gotovu datoteku s resursima (zakrpljena staklenka s upravljačkim programom - interclient.jar, zasebne klase resursa - interclient -rus.jar).

No čak i ako ste JDBC upravljački program podesili na željeno kodiranje, u nekim slučajevima možete naići na probleme. Na primjer, kada pokušavate koristiti prekrasne nove kursore za pomicanje standarda JDBC 2 u JDBC-ODBC mostu iz JDK 1.3.x, brzo ćete otkriti da ruska slova tamo jednostavno ne funkcioniraju (metoda updateString ()).

S ovom greškom povezana je mala priča. Kad sam ga prvi put otkrio (pod JDK 1.3 rc2), registrirao sam ga na BugParade (). Kada je izašla prva beta verzija JDK 1.3.1, ova je greška označena kao popravljena. Oduševljen, preuzeo sam ovu beta verziju, pokrenuo test - ne radi. O tome sam pisao Sun -ovci - u odgovoru su mi napisali da će popravak biti uključen u buduća izdanja. U redu, pomislio sam, pričekajmo. Vrijeme je prolazilo, objavljeno je izdanje 1.3.1, a zatim beta 1.4. Konačno sam odvojio vrijeme za provjeru - opet ne radi. Majko, majko, majko ... - odjek je odjeknuo uobičajeno. Nakon ljutitog pisma Suncu, uveli su novu grešku (), koju su dali indijskoj grani da je rastrga. Indijanci su petljali po kodu i rekli da je sve popravljeno u 1.4 beta3. Skinuo sam ovu verziju, pokrenuo testni slučaj ispod nje, evo rezultata -. Kako se ispostavilo, beta3 koji se distribuira na web mjestu (build 84) nije beta3 u koji je uključeno konačno popravljanje (build 87). Sada obećavaju da će popravak biti uključen u 1.4 rc1 ... Pa, općenito, razumijete :-)

Ruska slova u izvorima Java programa

Kao što je spomenuto, program prilikom izvođenja koristi Unicode. Izvorne datoteke zapisane su u običnim urednicima. Ja koristim Far, vjerojatno imate svog omiljenog urednika. Ovi uređivači spremaju datoteke u 8-bitnom formatu, što znači da se slično zaključivanje primjenjuje i na ove datoteke. Različite verzije prevoditelja izvode konverziju znakova nešto drugačije. Ranije verzije JDK 1.1.x koriste postavku file.encoding, koja se može nadjačati nestandardnom opcijom -J. U novijim (kako je izvijestio Denis Kokarev - počevši od 1.1.4) uveden je dodatni parametar -kodiranja, s kojim možete navesti kodiranje koje se koristi. U prevedenim razredima nizovi su predstavljeni u obliku Unicodea (točnije, u izmijenjenoj verziji UTF8 formata), pa se najzanimljivije događa tijekom kompilacije. Stoga je najvažnije saznati u kojem kodiranju vaše izvorne kodove i navesti točnu vrijednost prilikom sastavljanja. Prema zadanim postavkama koristit će se isti ozloglašeni file.encoding. Primjer pozivanja prevoditelja:

Osim korištenja ove postavke, postoji još jedna metoda - određivanje slova u "uXXXX" formatu, gdje je označen kod znaka. Ova metoda radi sa svim verzijama, a za dobivanje ovih kodova možete koristiti standardni alat.

Ako koristite bilo koji IDE, on može imati vlastite greške. Često ovi IDE -i koriste zadano kodiranje za čitanje / spremanje izvora - stoga obratite pozornost na regionalne postavke vašeg OS -a. Osim toga, mogu postojati očite pogreške - na primjer, prilično dobar CodeGuide IDE -skale ne probavlja dobro veliko rusko slovo "T". Ugrađeni analizator koda uzima ovo slovo kao dvostruki navodnik, što dovodi do činjenice da se ispravan kôd smatra pogrešnim. Možete se boriti protiv toga (zamjenom slova "T" kodom "u0422"), ali neugodno. Očigledno se negdje unutar raščlanjivača koristi eksplicitna pretvorba znakova u bajtove (poput: bajta b = (bajt) c), pa je umjesto koda 0x0422 (kôd slova "T") kôd 0x22 ( kod dvostrukog navodnika).

JBuilder ima još jedan problem, ali više je povezan s ergonomijom. Činjenica je da u JDK 1.3.0, pod kojim JBuilder radi prema zadanim postavkama, postoji greška () zbog koje novonastali prozori grafičkog sučelja, kada se aktiviraju, automatski uključuju raspored tipkovnice ovisno o regionalnim postavkama OS -a. Oni. ako imate ruske regionalne postavke, tada će se stalno pokušavati prebaciti na ruski izgled, što vam smeta pri pisanju programa. Web mjesto JBuilder.ru ima nekoliko zakrpa koje mijenjaju trenutnu lokaciju u JVM -u u Locale.US, ali najbolji način je nadogradnja na JDK 1.3.1, koja je ispravila ovu grešku.

Korisnici početnici JBuilder -a također mogu naići na takav problem - ruska slova se spremaju kao "uXXXX" kodovi. Da biste to izbjegli, u dijaloškom okviru Zadana svojstva projekta, kartica Općenito, u polju Kodiranje promijenite Zadano u Cp1251.

Ako za kompilaciju koristite ne standardni javac, već neki drugi prevoditelj - obratite pozornost na to kako izvodi konverziju znakova. Na primjer, neke verzije kompajlera IBM jikes ne razumiju da postoje druga kodiranja osim ISO-8859-1 :-). Postoje zakrpljene verzije u tom smislu, ali često se tu šiva i neko kodiranje - nema takve pogodnosti kao u javac.

JavaDoc

Za generiranje HTML dokumentacije za izvorni kod koristi se javadoc uslužni program koji je uključen u standardnu ​​JDK distribuciju. Za navođenje kodiranja ima čak 3 parametra:

  • -encoding - ova postavka navodi izvorno kodiranje. Zadana vrijednost je file.encoding.
  • -docencoding - ova postavka specificira kodiranje generiranih HTML datoteka. Zadana vrijednost je file.encoding.
  • -charset - ova postavka određuje skup znakova koji će biti zapisan u zaglavlja generiranih HTML datoteka ( ). Očito bi trebalo biti isto kao i prethodna postavka. Ako je ova postavka izostavljena, meta oznaka neće biti dodana.

Ruska slova u datotekama svojstava

Metode učitavanja resursa koriste se za čitanje datoteka svojstava koja rade na određeni način. Zapravo se za čitanje koristi metoda Properties.load koja ne koristi file.encoding (kodiranje ISO-8859-1 je kodirano u izvorima), pa je jedini način za navođenje ruskih slova upotreba formata "uXXXX" i komunalni.

Metoda Properties.save drugačije funkcionira u JDK 1.1 i 1.2. U verzijama 1.1 jednostavno je odbacio visoki bajt pa je ispravno radio samo s engleskim slovima. 1.2 vrši obrnutu pretvorbu u "uXXXX" tako da radi preslikano na metodu učitavanja.

Ako se datoteke svojstava ne učitavaju kao resursi, već kao obične konfiguracijske datoteke, a niste zadovoljni takvim ponašanjem, postoji samo jedan izlaz, napišite vlastiti učitavač.

Ruska slova u Servletima.

Pa, čemu služe ti isti Servleti, mislim da znate. Ako ne, najbolje je prvo pročitati dokumentaciju. Ovdje su opisane samo osobitosti rada s ruskim slovima.

Koje su značajke? Kada Servlet pošalje odgovor klijentu, postoje dva načina za slanje tog odgovora - putem OutputStream (metoda getOutputStream ()) ili putem PrintWriter (getWriter () metoda). U prvom slučaju pišete nizove bajtova, pa su gornje metode pisanja u streamove primjenjive. U slučaju PrintWriter -a, koristi postavljeno kodiranje. U svakom slučaju, potrebno je ispravno navesti kodiranje koje se koristi pri pozivanju metode setContentType (), kako bi se ispravna pretvorba znakova izvršila na strani poslužitelja. Ova se direktiva mora napraviti prije poziva getWriter () ili prije prvog pisanja u OutputStream. Primjer:

// Postavljanje kodiranja odgovora // Imajte na umu da neki motori ne dopuštaju // razmak između ';' i 'charset' response.setContentType ("text / html; charset = UTF-8"); PrintWriter out = response.getWriter (); // Otklanjanje pogrešaka imena kodiranja za provjeru out.println ("Kodiranje:" + odgovor.getCharacterEncoding ()); ... out.close (); )

Radi se o davanju odgovora klijentu. Nažalost, to nije tako jednostavno s ulaznim parametrima. Ulazni parametri kodirani su bajtom preglednika prema MIME vrsti "application / x-www-form-urlencoded". Kao što je rekao Aleksej Mendelev, preglednici kodiraju ruska slova koristeći trenutno postavljeno kodiranje. I, naravno, o tome se ništa ne izvještava. Sukladno tome, na primjer, u verzijama JSDK od 2.0 do 2.2, to se ni na koji način ne provjerava, a kakvo će se kodiranje koristiti za pretvorbu, ovisi o motoru koji se koristi. Počevši sa specifikacijom 2.3, postalo je moguće postaviti kodiranje za javax.servlet.ServletRequest - metodu setCharacterEncoding (). Najnovije verzije Resina i Tomcata već podržavaju ovu specifikaciju.

Dakle, ako imate sreće i imate poslužitelj s podrškom za Servlet 2.3, onda je sve vrlo jednostavno:

public void doPost (zahtjev HttpServletRequest, odgovor HttpServletResponse) baca ServletException, IOException ( // Kodiranje poruke request.setCharacterEncoding ("Cp1251"); Vrijednost niza = request.getParameter ("vrijednost"); ...

Postoji jedna značajna suptilnost u primjeni metode request.setCharacterEncoding () - ona se mora primijeniti prije prvi poziv na zahtjev za podacima (na primjer, request.getParameter ()). Ako koristite filtre koji obrađuju zahtjev prije nego što stigne u servlet, postoji šansa koja nije jednaka nuli da se u jednom od filtera neki parametar može pročitati iz zahtjeva (na primjer, za autorizaciju) i request.setCharacterEncoding () u servlet neće raditi ...

Stoga je ideološki ispravnije napisati filtar koji postavlja kodiranje zahtjeva. Štoviše, mora biti prvi u lancu filtara u web.xml.

Primjer takvog filtra:

uvoz java.io. *; uvoz java.util. *; uvoz javax.servlet. *; uvoz javax.servlet.http. *; javna klasa CharsetFilter implementira Filter (// kodira privatno kodiranje Stringa; javna void init (FilterConfig config) baca ServletException ( // čitanje iz konfiguracije encoding = config.getInitParameter ("requestEncoding"); // ako nije instaliran, instalirajte Cp1251 if (encoding == null) encoding = "Cp1251"; ) public void doFilter (ServletRequest zahtjev, ServletResponse odgovor, FilterChain next) baca IOException, ServletException (request.setCharacterEncoding (encoding); next.doFilter (zahtjev, odgovor);) public void kill () ())

I njegova konfiguracija u web.xml:

Filter znakova CharsetFilter Filter znakova /*

Ako nemate sreće i imate stariju verziju, morat ćete se izopačiti da biste postigli rezultat:

    Izvorni način rada s kodiranjima nudi ruski Apache - opisano je točno kako.

  • FOP

    Paket FOP dizajniran je za obradu dokumenata prema standardu XSL FO (Formating Objects). Konkretno, omogućuje vam stvaranje PDF dokumenata na temelju XML dokumenti... Paket FOP prema zadanim postavkama koristi Xalan XSLT procesor uparen s Xercesom za transformaciju iz izvornog XML -a u FO. Da biste stvorili konačnu sliku u FOP -u, morate povezati fontove koji podržavaju ruska slova. Evo kako to možete učiniti za verziju 0.20.1:

    1. Kopirajte datoteke ttf iz direktorija sustava Windows u poddirektorij conffonts (na primjer, u c: fop-0.20.1conffonts). Arial normal / normal, normal / bold, italic / normal i italic / bold zahtijevaju datoteke arial.ttf, arialbd.ttf, ariali.ttf i arialbi.ttf.
    2. Generirajte datoteke opisa fontova (poput arial.xml). Da biste to učinili, za svaki font morate pokrenuti naredbu (ovo je za Arial normalno / normalno, sve u jednom retku):
      java -cp .; c: fop-0.20.1uildfop.jar; c: fop-0.20.1libatik.jar; c: fop-0.20.1libxalan-2.0.0.jar; c: fop-0.20.1libxerces.jar; c: fop-0.20.1libjimi-1.0.jar org.apache.fop.fonts.apps.TTFReader fontsarial.ttf fontsarial.xml
    3. U FOP -u dodajte u conf / userconfig.xml opis fonta s ruskim slovima, poput:
      Arial normal / bold, italic / normal i italic / bold dodaju se na sličan način.
    4. Prilikom poziva FOP -a iz naredbeni redak nakon org.apache.fop.apps.Fop pisati -c c: fop -0.20.1confuserconfig.xml Ako trebate koristiti FOP iz servleta, morate u servlet nakon retka
      Vozač vozač= novi upravljački program ();
      dodaj redove:
      // Direktorij fontova (c: weblogicfonts) stvoren je samo radi praktičnosti. String userConfig = "fontovi / userconfig.xml"; Datoteka userConfigFile = nova datoteka (userConfig); Opcije opcija = nove Opcije (userConfigFile);
      Tada se može odrediti mjesto ttf datoteka u datoteci userconfig.xml u odnosu na korijen poslužitelja aplikacija, bez navođenja apsolutne staze:
    5. U datoteku FO (ili XML i XSL) prije upotrebe fonta upišite:
      font-family = "Arial" font-weight = "bold" (Ako koristite Arial bold) font-style = "italic" (Ako koristite Arial italic)

    Ovaj je algoritam poslao Alexey Tyurin, na čemu mu zahvaljuje posebno.

    Ako koristite preglednik ugrađen u FOP, morate uzeti u obzir njegove značajke. Konkretno, iako se pretpostavlja da su natpisi u njemu rusificirani, zapravo je to učinjeno s pogreškom (u verziji 0.19.0). Za učitavanje oznaka iz datoteka resursa, paket org.apache.fop.viewer.resources koristi svoj vlastiti učitavač (klasa org.apache.fop.viewer.LoadableProperties). Kodiranje čitanja je tamo teško kodirano (8859_1, kao u slučaju Properties.load ()), ali podrška za tip "uXXXX" nije implementirana. Ovu grešku prijavio sam programerima, uključili su popravak u svoje planove.

    Između ostalog, postoji stranica posvećena rusifikaciji FOP -a (http://www.openmechanics.org/rusfop/) Tamo možete pronaći distribucijski paket FOP -a s već popravljenim pogreškama i povezanim ruskim fontovima.

    CORBA

    CORBA nudi tip koji odgovara Java -inom nizu. Ovo je vrsta wstringa. Sve je u redu, ali neki CORBA poslužitelji ne podržavaju