JVM(1.5.x)でプログラムで使用されているデフォルトの文字エンコーディングを適切に設定する方法を教えてください。
私は-Dfile.encoding=whatever
が以前のJVMのための道であったことを読んだことがあります...私は私が入り込まない理由からそんなに贅沢を持っていません。
私が試してみました:
System.setProperty("file.encoding", "UTF-8");
プロパティは設定されますが、以下の最後のgetBytes呼び出しでUTF8を使用するようには思われません。
System.setProperty("file.encoding", "UTF-8");
byte inbytes[] = new byte[1024];
FileInputStream fis = new FileInputStream("response.txt");
fis.read(inbytes);
FileOutputStream fos = new FileOutputStream("response-2.txt");
String in = new String(inbytes, "UTF8");
fos.write(in.getBytes());
残念ながら、JVMの起動時にfile.encoding
プロパティを指定する必要があります。メインメソッドが入力されるまでに、String.getBytes()
とInputStreamReader
とOutputStreamWriter
のデフォルトコンストラクタで使用されている文字エンコーディングは恒久的にキャッシュされています。
Edward Grechが指摘するように、 このような特別な場合には、環境変数Java_TOOL_OPTIONS
canを使ってこのプロパティを指定しますが、通常は次のようにします。
Java -Dfile.encoding=UTF-8 … com.x.Main
Charset.defaultCharset()
はfile.encoding
プロパティへの変更を反映しますが、デフォルトの文字エンコーディングを決定する必要があるコアJavaライブラリ内のコードのほとんどはこのメカニズムを使用しません。
エンコードまたはデコードしているときは、file.encoding
プロパティまたはCharset.defaultCharset()
を照会して現在のデフォルトのエンコードを検索し、適切なメソッドまたはコンストラクタオーバーロードを使用してそれを指定できます。
JVM™Tool Interfaceから documentation…
たとえば組み込みVMや単にスクリプト内で起動された単純なVMなどでは、コマンドラインに常にアクセスしたり変更したりすることはできないため、このような場合にエージェントを起動できるように
Java_TOOL_OPTIONS
変数が用意されています。
(Windows)環境変数Java_TOOL_OPTIONS
を-Dfile.encoding=UTF8
に設定すると、(Java)System
プロパティはJVMが起動されるたびに自動的に設定されます。次のメッセージがSystem.err
に投稿されるため、パラメータが選択されたことがわかります。
Picked up Java_TOOL_OPTIONS: -Dfile.encoding=UTF8
私は間違いなくうまくいくハッキーな方法を持っています!
System.setProperty("file.encoding","UTF-8");
Field charset = Charset.class.getDeclaredField("defaultCharset");
charset.setAccessible(true);
charset.set(null,null);
このようにしてJVMをだまして、実行時にcharsetが設定されていないと判断し、再度UTF-8に設定するようにします。
私は、プラットフォームのデフォルトの文字セットを設定するよりも優れたアプローチがあると思います。特にプラットフォームに限らず、アプリケーションの展開に影響を与えることに制限があるように思われるので、もっと安全なString.getBytes("charsetName")
を呼び出すことです。そのようにして、あなたのアプリケーションはそのコントロールを超えたものに依存しません。
私は個人的にはString.getBytes()
は廃止されるべきだと感じています。これは、私が見た多くのケースで深刻な問題を引き起こしているからです。
私はあなたの最初の質問に答えることはできませんが、私はあなたにいくつかのアドバイスを提供したいと思います - JVMのデフォルトエンコーディングに頼らないでください。あなたのコードで希望するエンコーディング(すなわち "UTF-8")を明示的に指定することは常に最善です。そうすれば、異なるシステムやJVM構成でも機能することがわかります。
これを試して :
new OutputStreamWriter( new FileOutputStream("Your_file_fullpath" ),Charset.forName("UTF8"))
同じ問題がありました。この記事(および他の記事)からのいくつかの提案を系統的に試してみたが役に立たなかった。また、-Dfile.encoding = UTF8を追加してみましたが、何も機能していないようです。
この問題を抱えている人々のために、次の記事は最終的に私達がロケール設定がJava/Tomcatのunicode/UTF-8を壊すことができる方法について説明するのを助けました
http://www.jvmhost.com/articles/locale-breaks-unicode-utf-8-Java-Tomcat
〜/ .bashrcファイルでロケールを正しく設定することができました。
Spring Bootを使用していてJVMで引数file.encoding
を渡したい場合は、次のように実行する必要があります。
mvn spring-boot:run -Drun.jvmArguments="-Dfile.encoding=UTF-8"
これは私たちがJTwig
テンプレートを使っていて、オペレーティングシステムがSystem.out.println(System.getProperty("file.encoding"));
を通して見つけたANSI_X3.4-1968
を持っていたので私達に必要でした。
これが誰かに役立つことを願っています!
いろいろ試してみましたが、ここでのサンプルコードは完璧に動作します。 リンク
コードの要点は次のとおりです。
String s = "एक गाव में एक किसान";
String out = new String(s.getBytes("UTF-8"), "ISO-8859-1");
mvn clean install -Dfile.encoding=UTF-8 -Dmaven.repo.local=/path-to-m2
jenkinsタスクの設定中に、commandがexec-maven-pluginと連動して次のエラーを解決しました。
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512m; support was removed in 8.0
Error occurred during initialization of VM
Java.nio.charset.IllegalCharsetNameException: "UTF-8"
at Java.nio.charset.Charset.checkName(Charset.Java:315)
at Java.nio.charset.Charset.lookup2(Charset.Java:484)
at Java.nio.charset.Charset.lookup(Charset.Java:464)
at Java.nio.charset.Charset.defaultCharset(Charset.Java:609)
at Sun.nio.cs.StreamEncoder.forOutputStreamWriter(StreamEncoder.Java:56)
at Java.io.OutputStreamWriter.<init>(OutputStreamWriter.Java:111)
at Java.io.PrintStream.<init>(PrintStream.Java:104)
at Java.io.PrintStream.<init>(PrintStream.Java:151)
at Java.lang.System.newPrintStream(System.Java:1148)
at Java.lang.System.initializeSystemClass(System.Java:1192)
あなたが何をしているのかはっきりしておらず、現時点では管理できません。宛先ファイルに別のOutputStreamクラスを挿入できる場合は、定義した文字セットの下でStringsをバイトに変換するOutputStreamのサブタイプ(デフォルトではUTF-8など)を使用できます。変更されたUTF-8があなたのニーズに十分であれば、DataOutputStream.writeUTF(String)
を使うことができます。
byte inbytes[] = new byte[1024];
FileInputStream fis = new FileInputStream("response.txt");
fis.read(inbytes);
String in = new String(inbytes, "UTF8");
DataOutputStream out = new DataOutputStream(new FileOutputStream("response-2.txt"));
out.writeUTF(in); // no getBytes() here
このアプローチが実行不可能な場合は、データフローと実行環境の観点から制御できることとできないことをここで明確にしておくと役立ちます(ただし、決定したよりも簡単な場合があります)。がんばろう。
受け入れられた回答に対する@Casparのコメントに従うと、Sunに従ってこれを修正するための好ましい方法は次のとおりです。
「Javaプログラムを起動する前に、基盤となるプラットフォームのロケールを変更してください。」
http://bugs.Java.com/view_bug.do?bug_id=4163515
港湾労働者のために見なさい:
私のチームは、Windowsを搭載したマシンで同じ問題に遭遇しました。その後、2つの方法で問題を解決できました。
a)環境変数を設定します(Windowsシステム設定でも)
Java_TOOL_OPTIONS
-Dfile.encoding = UTF8
b)次のスニペットをpom.xmlに導入します。
-Dfile.encoding=UTF-8
内で
<jvmArguments>
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001
-Dfile.encoding=UTF-8
</jvmArguments>
最近私は地元の会社のノーツ6.5システムにぶつかり、ウェブメールがZhongwen以外のローカライズされたWindowsインストールで識別不可能な文字を表示することを発見しました。数週間前にオンラインで掘ったことがある、ほんの数分前にそれを考え出した:
Javaプロパティで、ランタイムパラメータに次の文字列を追加します。
-Dfile.encoding=MS950 -Duser.language=zh -Duser.country=TW -Dsun.jnu.encoding=MS950
この場合、UTF-8設定は機能しません。
私はAmazon(AWS)Elastic Beanstalkを使用していて、それをUTF-8に変更しました。
Elastic Beanstalkで、[設定]> [ソフトウェア]の[環境プロパティ]に移動します。 (value)-Dfile.encoding = UTF8を指定して(name)Java_TOOL_OPTIONSを追加します。
保存後、環境はUTF-8エンコーディングで再起動します。
2つのシステムプロパティをまとめて設定すると、システムはすべてをutf8に取り込むことができます。
file.encoding=UTF8
client.encoding.override=UTF-8