我正在编写一个Netbeans java程序来处理参数中的汉字。我能够在我的编码中使用unicode代码和中文字符,它们能够正确编译并显示在控制台上。然而,当我通过project properties run参数传递汉字时,它们都会变成?????。我已经将我的项目编码设置为UTF-8
和VM选项-Dfile。编码=UTF-8
。这是我的代码,请帮忙。
public static void main(String[] args) {
String test = "\u5973\u58eb";
System.out.println(test); //works
String test2 = "女士2";
System.out.println(test2); //works
System.out.println(args[0]); //copy&paste test2 to argument, not works, showing ??
}
NB:我使用jdk 1.8。0_202,蚂蚁v1.10.4,视窗10,网络豆10,用于网络豆输出和termianl的字体是monospaced14,项目是使用网络豆“java应用程序”创建的。当使用-Dfile.encoding=UTF-8
在Netbean或Windows命令提示符chcp 65001中运行时,会出现问题。
注意:根据skomisa的建议,我进一步测试了视窗“使用Unicode utf8进行全球语言支持”。我也远离Netbean,但使用jar在chcp 65001的Windows cmd上运行。
D:\.......>java -cp dist/myjar.jar -Dfile.encoding=UTF8 java.mypackage.TestUTF8 女士
女士
女士2
女士
D:\.......>java -cp dist/myjar.jar java.mypackage.TestUTF8 女士
??
??2
女士
所以使用-Dfile。encoding=UTF8(首次运行),编码中的常量字符串有效,而参数无效。没有
-d文件。编码
(第二次运行),在代码中常量不起作用,而参数起作用。但我两者都需要。我的程序和程序参数中都有中文常量字符串。谁能告诉我能做些什么吗。
基于对类似问题的回答,似乎将Unicode参数传递给Java应用程序从未正常工作过。没有简单的解决方案,但可以使用JNA(Java原生访问)解决这个问题。
JNA允许您从Java调用Windows API方法,而无需使用native
code。因此,在Java应用程序中,可以直接调用Win API方法,例如GetCommandLineW()
和CommandLineToArgvW()
,以访问用于调用程序的命令行的详细信息,包括传递的任何参数。这两种方法都支持Unicode。
实现这一点的代码并不琐碎,但也不太复杂。下面的方法基于Sergey Karpushin的代码,该代码回答了将命令行unicode参数传递给Java代码的问题
要编译代码,您需要几个JAR:jna。jar和jna平台。罐子您可以从JNA 5.10.0下载的dist目录或Maven获取这些信息。
这种方法既适用于NetBeans,也适用于Windows 10上的命令行,不过有一些显著的区别:
CommandLineToArgvW()
返回的参数时,您可能会看到NetBeans中返回的参数与从命令行返回的参数之间存在差异。但这并不是一个真正的问题,因为您感兴趣的唯一参数是末尾的参数,它们位于包含jar文件名的参数之后
这是代码:
package chinesearg;
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;
import java.util.ArrayList;
import java.util.List;
// Proof of concept application which uses JNA to correctly process command
// line arguments containing Chinese characters using JNA.
//
// Credit to Sergey Karpushin for the approach used in this this code.
// See this SO answer: https://stackoverflow.com/a/41923480/2985643
public class ChineseArg {
private final Kernel32 kernel32 = Native.load("kernel32", Kernel32.class);
private final Shell32 shell32 = Native.load("shell32", Shell32.class);
public static void main(String[] args) {
String test = "\u5973\u58eb";
System.out.println(test); //works
String test2 = "女士2";
System.out.println(test2); //works
System.out.println("args.length=" + args.length);
for (int i=0; i< args.length; i++) {
System.out.println("args[" + i + "] = "+args[i]);
}
String[] params = new ChineseArg().getCommandLineArguments();
if (params == null) {
System.out.println("getCommandLineArguments() returned null.");
} else {
int count = params.length;
System.out.println("Number of params=" + count);
for (int i = 0; i < count; i++) {
System.out.println("params[" + i + "]=" + params[i]);
}
}
}
private String[] getCommandLineArguments() {
System.out.println("Active code page is " + Kernel32.INSTANCE.GetConsoleCP());
String[] ret = getFullCommandLine();
List<String> 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]);
}
return ret;
}
private String[] getFullCommandLine() {
IntByReference argc = new IntByReference();
Pointer argv_ptr = shell32.CommandLineToArgvW(kernel32.GetCommandLineW(), argc);
String[] argv = argv_ptr.getWideStringArray(0, argc.getValue());
kernel32.LocalFree(argv_ptr);
return argv;
}
}
interface Kernel32 extends StdCallLibrary {
static Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class, com.sun.jna.win32.W32APIOptions.DEFAULT_OPTIONS);
WString GetCommandLineW();
int GetConsoleCP();
Pointer LocalFree(Pointer pointer);
}
interface Shell32 extends StdCallLibrary {
Pointer CommandLineToArgvW(WString command_line, IntByReference argc);
}
这是从命令提示符运行时的示例输出,显示第一个参数(“女士2”)被正确捕获:
C:\Users\johndoe>chcp 65001
Active code page: 65001
C:\Users\johndoe>java -Dfile.encoding=UTF-8 -jar "D:\NB126\ChineseArg\dist\ChineseArg.jar" "女士2" "\u5973\u58eb"
女士
女士2
args.length=2
args[0] = ??2
args[1] = \u5973\u58eb
Active code page is 65001
Number of params=2
params[0]=女士2
params[1]=\u5973\u58eb
C:\Users\johndoe>
笔记:
我是vaadin的新手,当我试图创建一个新的项目时,出现了这个问题...我在谷歌上看了看,但找不到任何解决方案 总时间:4.665秒完成时间:Sat Jun 03 23:53:27 NPT 2017
如何更改项目运行时平台? (standard NetBeans[8.1]Java Project[Java Application]) 详细信息: 在NetBeans 8.1中使用Ubuntu 我已经安装了JDK 1.6,JDK 1.7+JDK 1.8 我的项目平台是Java6. 我的系统默认Java是Java7。 NetBeans-IDE是用Java8启动的。 我想要的是: Project-Pl
我是java语言的新手。我试着做我的第一个节目参考YouTube。但当我点击“运行”按钮时,它就不起作用了。我不知道为什么,但所有的构建或代码都是成功的。也许我有一些小错误…(?)有人能帮忙吗?在此输入图像说明
问题内容: 我正在编写一个maven插件,该插件必须使用特定的VM参数来初始化另一个Java项目。根据exec:java的介绍,它们仅接受参数,而不接受VMarguments,因此我的问题是如何从命令行启动具有特定VMarguments的Java项目?谢谢 问题答案: 如果使用Maven的exec:java插件,则无法提供额外的VM参数,因为它在同一VM中运行(即,它已经被初始化)。您将需要使用e
Project 对象提供了一些标准的属性,您可以在构建脚本中很方便的使用他们. 下面列出了常用的属性: Name Type Default Value project Project Project 实例对象 name String 项目目录的名称 path String 项目的绝对路径 description String 项目描述 projectDir File 包含构建脚本的目录 build
我正在使用Netbean 8.2(虽然这个问题在以前的版本中一直存在)。我可以创建一个maven项目,将以前的项目剪切并传递到该项目中,然后构建该项目并运行它,没有问题。 但是,当我关闭netbeans时,maven项目变成了java项目,我能找到的唯一修复方法是创建一个新的maven项目,并重复剪切和保存。 必须有一个更好的解决方案,如果有人有类似的问题,并解决了它,请让我知道! 非常感谢您的帮