2008-09-10 20 views
10

Staramy się używać Java i UTF-8 w systemie Windows. Aplikacja zapisuje logi na konsoli i chcielibyśmy używać UTF-8 do logów, ponieważ nasza aplikacja ma umiędzynarodowione logi.Java, UTF-8 i Windows konsola

Możliwe jest skonfigurowanie maszyny JVM tak, aby generowała kodowanie UTF-8, używając -Dfile.encoding=UTF-8 jako argumentów dla maszyny JVM. Działa dobrze, ale dane wyjściowe na konsoli systemu Windows są zniekształcone.

Następnie możemy ustawić stronę kodową konsoli na 65001 (chcp 65001), ale w tym przypadku pliki .bat nie działają. Oznacza to, że gdy próbujemy uruchomić naszą aplikację za pomocą naszego skryptu (o nazwie start.bat), absolutnie nic się nie dzieje. Komenda proste zwroty:

C:\Application> chcp 65001 
Activated code page: 65001 
C:\Application> start.bat 

C:\Application> 

Ale bez chcp 65001, nie ma problemu, a aplikacja może być uruchomiona.

Jakieś wskazówki na ten temat?

+0

Co to jest kodowanie tekstowe pliku start.bat? – johnstok

Odpowiedz

6

Spróbuj chcp 65001 && start.bat

+0

To musi być używane w połączeniu z -Dfile.encoding = UTF-8, aby działało poprawnie. –

+0

@AxelFontaine Próbowałem użyć -Dfile.encoding = UTF-8, ale przy użyciu symbolu pierwiastka kwadratowego ostatnie 2 cyfry po symbolu powtarzały się. E.g zamiast "√125" wyjście będzie "√12525" – Cj1m

-4

Czy wypróbowałeś PowerShell zamiast starego cmd.exe.

+1

PowerShell nadal używa tej samej konsoli, więc jest tak samo stary i gówniany jak cmd.exe. – Trejkaz

0

Mieliśmy kilka podobnych problemów w systemie Linux. Nasz kod był w ISO-8859-1 (głównie kompatybilny z cp-1252), ale konsola była w UTF-8, dzięki czemu kod nie został skompilowany. Po prostu zmiana konsoli na ISO-8859-1 spowodowałaby pęknięcie skryptu budowania w UTF-8. Znaleźliśmy kilka możliwości:
1- zdefiniować standardowe kodowanie i przykleić do niego. To był nasz wybór. Zdecydowaliśmy się zachować wszystko w ISO-8859-1, modyfikując skrypty budowania.
2- Ustawianie kodowania przed rozpoczęciem dowolnego zadania, nawet wewnątrz skryptów budujących. Jakiś kod, jak powiedział erickson. W Linuksie było to:

lang=pt_BR.ISO-8859-1 /usr/local/xxxx 

Moje zaćmienie jest nadal takie. Oba działają dobrze.

+0

Wygląda jak krok w tył, aby przykleić (i zmodyfikować rzeczy) do iso-8859-1 zamiast utf-8. Ale prawdopodobnie miałeś swoje powody. – KarolDepka

6

Java w systemie Windows nie obsługuje Unicode Ouput domyślnie. Napisałem metodę obejścia problemu, wywołując Native API z biblioteką JNA. Metoda wywoła WriteConsoleW dla wyjścia Unicode na konsoli.

import com.sun.jna.Native; 
import com.sun.jna.Pointer; 
import com.sun.jna.ptr.IntByReference; 
import com.sun.jna.win32.StdCallLibrary; 

/** For unicode output on windows platform 
* @author Sandy_Yin 
* 
*/ 
public class Console { 
    private static Kernel32 INSTANCE = null; 

    public interface Kernel32 extends StdCallLibrary { 
     public Pointer GetStdHandle(int nStdHandle); 

     public boolean WriteConsoleW(Pointer hConsoleOutput, char[] lpBuffer, 
       int nNumberOfCharsToWrite, 
       IntByReference lpNumberOfCharsWritten, Pointer lpReserved); 
    } 

    static { 
     String os = System.getProperty("os.name").toLowerCase(); 
     if (os.startsWith("win")) { 
      INSTANCE = (Kernel32) Native 
        .loadLibrary("kernel32", Kernel32.class); 
     } 
    } 

    public static void println(String message) { 
     boolean successful = false; 
     if (INSTANCE != null) { 
      Pointer handle = INSTANCE.GetStdHandle(-11); 
      char[] buffer = message.toCharArray(); 
      IntByReference lpNumberOfCharsWritten = new IntByReference(); 
      successful = INSTANCE.WriteConsoleW(handle, buffer, buffer.length, 
        lpNumberOfCharsWritten, null); 
      if(successful){ 
       System.out.println(); 
      } 
     } 
     if (!successful) { 
      System.out.println(message); 
     } 
    } 
}