2015-07-14 18 views
17

znajduje się plik o nazwie "dd.txt" na moim dysku, to zawartość jest \u5730\u7406Jaka jest różnica między ciągiem znaków w kodzie źródłowym a ciągiem odczytanym z pliku?

teraz, kiedy uruchomić ten program

public static void main(String[] args) throws IOException { 
    FileInputStream fis=new FileInputStream("d:\\dd.txt"); 
    ByteArrayOutputStream baos=new ByteArrayOutputStream(); 
    byte[] buffer=new byte[fis.available()]; 
    while ((fis.read(buffer))!=-1) { 
     baos.write(buffer); 
    } 
    String s1="\u5730\u7406"; 
    String s2=baos.toString("utf-8"); 
    System.out.println("s1:"+s1+"\n"+"s2:"+s2); 
} 

i mam inny wynik

s1:地理 
s2:\u5730\u7406 

czy możesz mi powiedzieć, dlaczego? i jak mogę przeczytać ten plik i uzyskać taki sam wynik jak s1 w języku chińskim?

+4

Ponieważ _kompilator_ zastępuje przed skompilowaniem czegokolwiek. –

+4

Notatka boczna: fis.available() informuje, ile bajtów można odczytać bez blokowania. Nie informuje o długości wejścia (pliku). – haraldK

+0

dziękuję wszystkim .. –

Odpowiedz

30

Podczas pisania \u5730 w kodzie Java, jest interpretowany jako jeden znak Unicode (literał unicode) przez kompilator. Kiedy piszesz to samo do pliku, to tylko 6 zwykłych znaków (ponieważ nic nie interpretuje tego). Czy istnieje powód, dla którego nie piszesz bezpośrednio do pliku 地理?

Jeśli chcesz przeczytać plik zawierający literały Unicode, musisz sam zanalizować wartości, odrzucając \u i parsując kodek kodu Unicode. O wiele łatwiej jest po prostu napisać odpowiedni kod Unicode z odpowiednim kodowaniem (np. UTF-8) w pliku w pierwszej kolejności, jeśli kontrolujesz tworzenie pliku, aw normalnych okolicznościach nigdy nie powinieneś natknąć się na pliki zawierające te uciekłe znaki Unicode .

+0

Jestem tylko ciekawy i chcę wiedzieć, dlaczego. Dziękuję Ci ! –

+9

@PaulWang, jeśli odpowiedziałeś na twoje pytanie, rozważ [zaakceptowanie] (https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). To nie tylko daje trochę powtórzeń, ale także robi dwie inne rzeczy - 1) wskazuje społeczności, że to pytanie zostało udzielone i 2) wskazuje przyszłym czytelnikom, którzy odpowiedzą na pytanie, jak rozwiązać twój problem. –

6

W kodzie Java \uxxxx są interpretowane jako jako literały Unicode, więc są one wyświetlane jako chińskie znaki. Dzieje się tak tylko dlatego, że kompilator jest poinstruowany, aby to zrobić.

Aby uzyskać ten sam rezultat, co musisz zrobić, niektóre parsowania siebie:

String[] hexCodes = s2.split("\\\\u"); 
for (String hexCode : hexCodes) { 
    if (hexCode.length() == 0) 
     continue; 
    int intValue = Integer.parseInt(hexCode, 16); 
    System.out.print((char)intValue); 
} 

(Zauważ, że to działa tylko wtedy, gdy każdy znak jest w Unicode dosłownej formie, np \uxxxx)

+0

Już to rozumiem, dziękuję! –

+0

Występują dwa problemy w twoich kodach. –

+0

1, ciąg używany do podziału powinien być "\\\\ u" 2. Pierwszy element tych tablic ciągów znaków jest pusty po rozszczepieniu obiektu ciągu. –

2

Spróbuj tego:

static final Pattern UNICODE_ESCAPE = Pattern.compile("\\\\u([0-9a-fA-F]{4})"); 

static String decodeUnicodeEscape(String s) { 
    StringBuilder sb = new StringBuilder(); 
    int start = 0; 
    Matcher m = UNICODE_ESCAPE.matcher(s); 
    while (m.find()) { 
     sb.append(s.substring(start, m.start())); 
     sb.append((char)Integer.parseInt(m.group(1), 16)); 
     start = m.end(); 
    } 
    sb.append(s.substring(start)); 
    return sb.toString(); 
} 

public static void main(String[] args) throws IOException { 
    // your code .... 
    String s1="\u5730\u7406"; 
    String s2= decodeUnicodeEscape(baos.toString("utf-8")); 
    System.out.println("s1:"+s1+"\n"+"s2:"+s2); 
} 
+0

dziękuję, twoja odpowiedź jest idealna! –

+0

Należy pamiętać, że będzie to obsługiwane tylko znaki Unicode, które pasują do jednego znaku. Dla reszty z nich spróbuj tego: 'sb.append (new String (Character.toChars (Integer.parseInt (m.group (1), 16))))'). [Więcej szczegółów] (https://stackoverflow.com/questions/5585919/creating-unicode-character-from-its-number/16034658#16034658) – eis

+0

@eis wczoraj, Mój kod działa również dla zastępczych par. – saka1029

Powiązane problemy