Pasar el argumento Unicode de la línea de comando al código Java

Tengo que pasar el argumento de línea de comando que es el método principal de japonés a Java. Si escribo caracteres Unicode en la ventana de línea de comandos, aparece ‘?????’ lo cual está bien, pero el valor pasado al progtwig java también es ‘?????’. ¿Cómo obtengo el valor correcto del argumento pasado por la ventana de comandos? A continuación se muestra un progtwig de ejemplo que escribe en un archivo el valor proporcionado por el argumento de línea de comando.

public static void main(String[] args) { String input = args[0]; try { String filePath = "C:/Temp/abc.txt"; File file = new File(filePath); OutputStream out = new FileOutputStream(file); byte buf[] = new byte[1024]; int len; InputStream is = new ByteArrayInputStream(input.getBytes()); while ((len = is.read(buf)) > 0) { out.write(buf, 0, len); } out.close(); is.close(); } catch (Exception e) { e.printStackTrace(); } } 

Desafortunadamente no se pueden usar de manera confiable caracteres que no sean ASCII con aplicaciones de línea de comandos que usan stdlib del tiempo de ejecución de Windows C, como Java (y prácticamente todos los lenguajes de scripting no específicos de Windows).

Esto se debe a que leen sus entradas y salidas utilizando una página de códigos específicos de la configuración regional de forma predeterminada, que nunca es un UTF, a diferencia de cualquier otro sistema operativo moderno que utilice UTF-8.

Si bien puede cambiar la página de códigos de un terminal por otra cosa utilizando el comando chcp , la compatibilidad con la encoding UTF-8 bajo chcp 65001 se interrumpe de varias maneras que probablemente chcp 65001 muerte de las aplicaciones.

Si solo necesita japonés, puede cambiar a la página de códigos 932 (similar a Shift-JIS) configurando su configuración regional (‘idioma para aplicaciones que no son Unicode’ en la configuración Regional) en Japón. Sin embargo, esto aún fallará para los personajes que no están en esa página de códigos.

Si necesita obtener caracteres que no sean ASCII a través de la línea de comando de manera confiable en Windows, debe llamar directamente a la función GetCommandLineW API GetCommandLineW para evitar la capa de encode-to-system-code-page. Probablemente quieras hacer eso usando JNA.

Desafortunadamente, el iniciador de Java estándar tiene un error conocido y de larga vida en el manejo de argumentos de línea de comandos Unicode en Windows. Quizás en algunas otras plataformas también. Para Java 7 actualización 1 todavía estaba en su lugar.

Si te sientes bien progtwigndo en C / C ++, puedes intentar escribir tu propio lanzador. Algunos lanzadores especializados podrían no ser un gran problema … Solo vea el ejemplo inicial en la página API de Invocación de JNI .

Otra posibilidad es usar una combinación de un contenedor Java y un archivo temporal para pasar parámetros Unicode a una aplicación Java. Ver mi blog Java, Xalan, Unicode argumentos de la línea de comandos … para más comentarios y el código del contenedor.

El problema se debe a la configuración regional del sistema. Cambie su configuración regional a japonés y funcionaría.

A continuación, se indica cómo hacer esto http://www.java.com/en/download/help/locale.xml

Puede usar JNA para obtener eso, aquí está copiar y pegar de mi código:

 import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.log4j.Logger; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.WString; import com.sun.jna.ptr.IntByReference; import com.sun.jna.win32.StdCallLibrary; public class OsNativeWindowsImpl implements OsNative { private static Logger log = Logger.getLogger(OsNativeWindowsImpl.class); private Kernel32 kernel32; private Shell32 shell32; /** * This method will try to solve issue when java executable cannot transfer * argument in utf encoding. cyrillic languages screws up and application * receives ??????? instead of real text */ @Override public String[] getCommandLineArguments(String[] fallBackTo) { try { log.debug("In case we fail fallback would happen to: " + Arrays.toString(fallBackTo)); String[] ret = getFullCommandLine(); log.debug("According to Windows API programm was started with arguments: " + Arrays.toString(ret)); List argsOnly = null; for (int i = 0; i < ret.length; i++) { if (argsOnly != null) { argsOnly.add(ret[i]); } else if (ret[i].toLowerCase().endsWith(".jar")) { argsOnly = new ArrayList<>(); } } if (argsOnly != null) { ret = argsOnly.toArray(new String[0]); } log.debug("These arguments will be used: " + Arrays.toString(ret)); return ret; } catch (Throwable t) { log.error("Failed to use JNA to get current program command line arguments", t); return fallBackTo; } } private String[] getFullCommandLine() { try { // int pid = kernel32.GetCurrentProcessId(); IntByReference argc = new IntByReference(); Pointer argv_ptr = getShell32().CommandLineToArgvW(getKernel32().GetCommandLineW(), argc); String[] argv = argv_ptr.getWideStringArray(0, argc.getValue()); getKernel32().LocalFree(argv_ptr); return argv; } catch (Throwable t) { throw new RuntimeException("Failed to get program arguments using JNA", t); } } private Kernel32 getKernel32() { if (kernel32 == null) { kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class); } return kernel32; } private Shell32 getShell32() { if (shell32 == null) { shell32 = (Shell32) Native.loadLibrary("shell32", Shell32.class); } return shell32; } } interface Kernel32 extends StdCallLibrary { int GetCurrentProcessId(); WString GetCommandLineW(); Pointer LocalFree(Pointer pointer); } interface Shell32 extends StdCallLibrary { Pointer CommandLineToArgvW(WString command_line, IntByReference argc); } 

Además del conocido log4j este código también depende de

  net.java.dev.jna jna 4.3.0  

Java funciona internamente con Unicode, por lo que cuando se comstackn archivos de código fuente que utilizan una encoding china como Big5 o GB2312, debe especificar la encoding al comstackdor para convertirla adecuadamente a Unicode.

 javac -encoding big5 sourcefile.java 

o

 javac -encoding gb2312 sourcefile.java 

Referencia: http://www.chinesecomputing.com/programming/java.html