डिफ़ॉल्ट जावा वर्ण एन्कोडिंग सेट करना


362

मैं जेवीएम (1.5.x) प्रोग्राम द्वारा उपयोग किए जाने वाले डिफ़ॉल्ट चरित्र एन्कोडिंग को ठीक से कैसे सेट करूं?

मैंने पढ़ा है कि -Dfile.encoding=whateverपुराने JVM के लिए जाने का रास्ता हुआ करता था। मेरे पास वह विलासिता नहीं है जिसकी वजह से मैं अभ्यस्त हो गया हूं।

मैंने कोशिश की है:

System.setProperty("file.encoding", "UTF-8");

और संपत्ति सेट हो जाती है, लेकिन यह getBytesयूटीएफ 8 का उपयोग करने के लिए नीचे अंतिम कॉल का कारण नहीं लगता है :

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());

उत्कृष्ट टिप्पणियाँ दोस्तों - और चीजें जो मैं पहले से ही खुद सोच रहा था। दुर्भाग्य से एक अंतर्निहित String.getBytes () कॉल है जिसका मेरे पास कोई नियंत्रण नहीं है। एकमात्र तरीका जिसे मैं वर्तमान में देख रहा हूं, वह डिफ़ॉल्ट एन्कोडिंग को प्रोग्रामेटिक रूप से सेट करना है। कोई अन्य सुझाव?

6
शायद अप्रासंगिक प्रश्न लेकिन, क्या तब अंतर होता है जब UTF8 को "UTF8", "UTF-8" या "utf8" के साथ सेट किया जाता है। हाल ही में मैंने पाया कि IBM WAS 6.1 EJB और WEB कंटेनर अलग-अलग तरह से व्यवहार करते हैं (केस-सेंसिटिविटी के रूप में) स्ट्रिंग्स एन्कोडिंग को परिभाषित करते थे।
igor.beslic

5
बस एक विवरण लेकिन: UTF-8 से UTF8 को प्राथमिकता दें (केवल पूर्व मानक है)। यह अभी भी 2012 में लागू होता है ...
क्रिस्टोफ़ रूसो

4
file.encodingसंपत्ति सेट करना या पढ़ना समर्थित नहीं है
McDowell

@erickson Am अभी भी क्वेरी के साथ स्पष्ट नहीं है, यह नहीं सच है कि, "file.encoding" प्रासंगिक जब चरित्र आधारित आई / ओ धाराओं (के सभी उपवर्गों उपयोग किया जाता है class Readerऔर class Writer)? क्योंकि class FileInputStreamबाइट आधारित I / O स्ट्रीम है, इसलिए किसी को बाइट-आधारित I / O स्ट्रीम में सेट कैरेक्टर की परवाह क्यों करनी चाहिए?
ओवरएक्सचेंज

जवाबों:


311

दुर्भाग्य से, file.encodingसंपत्ति को निर्दिष्ट करना होगा क्योंकि जेवीएम शुरू होता है; समय आपका मुख्य विधि दर्ज किया गया है द्वारा, चरित्र द्वारा प्रयुक्त एन्कोडिंग String.getBytes()और के डिफ़ॉल्ट कंस्ट्रक्टर्स InputStreamReaderऔर OutputStreamWriterस्थायी रूप से कैश किए गए।

जैसा कि एडवर्ड ग्रेच बताते हैं, इस तरह के एक विशेष मामले में, इस संपत्ति को निर्दिष्ट करने के लिए पर्यावरण चर JAVA_TOOL_OPTIONS का उपयोग किया जा सकता है, लेकिन यह आमतौर पर इस तरह है:

java -Dfile.encoding=UTF-8  com.x.Main

Charset.defaultCharset()file.encodingसंपत्ति में परिवर्तनों को प्रतिबिंबित करेगा , लेकिन मुख्य जावा पुस्तकालयों में अधिकांश कोड जो डिफ़ॉल्ट चरित्र एन्कोडिंग को निर्धारित करने की आवश्यकता है, इस तंत्र का उपयोग नहीं करते हैं।

जब आप एन्कोडिंग या डिकोडिंग कर रहे हैं, तो आप file.encodingसंपत्ति को क्वेरी कर सकते हैं या Charset.defaultCharset()वर्तमान डिफ़ॉल्ट एन्कोडिंग को खोजने के लिए, और इसे निर्दिष्ट करने के लिए उपयुक्त विधि या कंस्ट्रक्टर अधिभार का उपयोग कर सकते हैं।


9
पूर्णता के लिए मैं यह जोड़ना चाहूंगा कि थोड़ी सी चालाकी के साथ आप वास्तव में उपयोग किए गए डिफ़ॉल्ट एन्कोडिंग (जैसा कि कैश किया गया है) के लिए प्राप्त कर सकते हैं, गैरी क्रोनिन के लिए धन्यवाद: बाइट [] बाइटअरे = {'ए'}; InputStream inputStream = new ByteArrayInputStream (byteArray); InputStreamReader रीडर = नया InputStreamReader (inputStream); स्ट्रिंग defaultEncoding = Reader.getEncoding (); lists.xcf.berkeley.edu/lists/advanced-java/1999-October/…
Stijn de Witt

2
JDK-4163515 में file.encodingJVM स्टार्टअप के बाद sysprop सेट करने के बारे में कुछ और जानकारी है ।
कैस्पर

2
मैं अपने सिर को खरोंच कर रहा था क्योंकि कमांड विंडोज, लिनक्स और मैक पर पूरी तरह से काम नहीं कर रहा था ... तो मैंने "इस तरह से मूल्य के आसपास" डाल दिया: जावा -डी "file.encoding = UTF-8"
-jar

जावा स्प्रिंग बूट के मामले में मेरे उत्तर की जाँच करें: stackoverflow.com/a/48952844/986160
माइकल फिलालिडिस

170

से JVM ™ उपकरण इंटरफ़ेस प्रलेखन ...

चूंकि कमांड-लाइन को हमेशा एक्सेस या संशोधित नहीं किया जा सकता है, उदाहरण के लिए एम्बेडेड वीएम में या बस वीएम स्क्रिप्ट के भीतर गहराई से लॉन्च किया जाता है, JAVA_TOOL_OPTIONSइसलिए एक चर प्रदान किया जाता है ताकि एजेंटों को इन मामलों में लॉन्च किया जा सके।

(विंडोज़) वातावरण चर की स्थापना करके JAVA_TOOL_OPTIONSकरने के लिए -Dfile.encoding=UTF8, (जावा) Systemसंपत्ति स्वचालित रूप से हर बार एक JVM शुरू कर दिया है स्थापित किया जाएगा। आपको पता चल जाएगा कि पैरामीटर को उठाया गया है क्योंकि निम्नलिखित संदेश को निम्न पर पोस्ट किया जाएगा System.err:

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8


क्या आप जानते हैं कि "पिक अप ..." स्टेटमेंट टॉमकैट लॉग में छपा होगा?
thatidiotguy

1
हाय एडवर्ड ग्रेच मैं आपके समाधान के लिए धन्यवाद देता हूं। यह एक और मंच पोस्ट में मेरी प्रोब्लम को हल किया गया था। stackoverflow.com/questions/14814230/…
स्मॉग

8
UTF8या UTF-8?
टिनी

1
@ टाइनी जावा दोनों को समझता है। stackoverflow.com/questions/6031877/…
DLight

आपके समाधान ने मेरा समय बचाया, बहुत बहुत धन्यवाद !!
शोभन

67

मेरे पास हैकी तरीका है जो निश्चित रूप से काम करता है !!

System.setProperty("file.encoding","UTF-8");
Field charset = Charset.class.getDeclaredField("defaultCharset");
charset.setAccessible(true);
charset.set(null,null);

इस तरह से आप JVM को ट्रिक करने जा रहे हैं जो यह सोचेगा कि charset सेट नहीं है और इसे रन-वे पर UTF-8 में फिर से सेट करने के लिए बनाएं!


2
मेरे लिए NoSuchFieldException
SparK

10
हैक के लिए काम करने के लिए, आपको लगता है कि सुरक्षा प्रबंधक बंद है। यदि आपके पास JVM ध्वज सेट करने का कोई तरीका नहीं है, तो आपके पास सुरक्षा प्रबंधक सक्षम प्रणाली भी हो सकती है।
योनातन

3
JDK9 अब इस हैक को स्वीकार नहीं करता है । WARNING: An illegal reflective access operation has occurred • WARNING: Illegal reflective access by [..] • WARNING: Please consider reporting this to the maintainers of [..] • WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations • WARNING: All illegal access operations will be denied in a future release
डॉटविन

1
@Enerccio: यह एक अच्छा जवाब नहीं है, यह एक गंदा हैक है, और ऐसा होने की प्रतीक्षा में एक समस्या है। जिसका उपयोग केवल आपातकालीन उपाय के रूप में किया जाना चाहिए।
sleske

1
@Enerccio: यह तर्कपूर्ण है कि क्या जावा "को इसे सेट करने का एक तरीका होना चाहिए - एक यह भी तर्क दे सकता है कि डेवलपर्स को" प्रासंगिक रूप से जब भी प्रासंगिक हो "एन्कोडिंग को स्पष्ट रूप से निर्दिष्ट करना चाहिए। किसी भी दर पर, इस समाधान में लंबे समय तक गंभीर समस्या पैदा करने की क्षमता है, इसलिए "आपातकालीन उपयोग के लिए" केवल चेतावनी। वास्तव में, यहां तक कि आपातकालीन उपयोग संदिग्ध है, क्योंकि वहाँ है यह करने का एक समर्थित तरह से, JAVA_TOOL_OPTIONS सेटिंग के रूप में एक और उत्तर में विस्तार से बताया।
sleske

38

मुझे लगता है कि प्लेटफ़ॉर्म के डिफ़ॉल्ट चरित्र सेट को सेट करने से बेहतर दृष्टिकोण है, खासकर जब आपको लगता है कि एप्लिकेशन परिनियोजन को प्रभावित करने पर प्रतिबंध है, तो प्लेटफ़ॉर्म को अकेले रहने दें, ज्यादा सुरक्षित कॉल करना है String.getBytes("charsetName")। इस तरह आपका आवेदन उसके नियंत्रण से परे चीजों पर निर्भर नहीं है।

मुझे व्यक्तिगत रूप से लगता है कि String.getBytes()पदावनत किया जाना चाहिए, क्योंकि इसने मेरे द्वारा देखे गए कई मामलों में गंभीर समस्याएं पैदा की हैं, जहां डेवलपर डिफ़ॉल्ट रूप से संभवतया बदलते समय के लिए जिम्मेदार नहीं था।


18

मैं आपके मूल प्रश्न का उत्तर नहीं दे सकता, लेकिन मैं आपको कुछ सलाह देना चाहूंगा - जेवीएम के डिफ़ॉल्ट एन्कोडिंग पर निर्भर न हों। अपने कोड में वांछित एन्कोडिंग (यानी "UTF-8") को स्पष्ट रूप से निर्दिष्ट करना हमेशा सबसे अच्छा होता है। इस तरह, आप जानते हैं कि यह विभिन्न प्रणालियों और JVM विन्यासों पर भी काम करेगा।


7
इसके अलावा, निश्चित रूप से, यदि आप एक डेस्कटॉप ऐप लिख रहे हैं और कुछ उपयोगकर्ता-निर्दिष्ट पाठ को संसाधित कर रहे हैं जिसमें कोई एन्कोडिंग मेटाडेटा नहीं है - तो प्लेटफ़ॉर्म डिफ़ॉल्ट एन्कोडिंग आपका सबसे अच्छा अनुमान है कि उपयोगकर्ता क्या उपयोग कर रहा है।
माइकल बोर्गवर्ड

@MichaelBorgwardt "तो प्लेटफ़ॉर्म डिफ़ॉल्ट एन्कोडिंग आपका सबसे अच्छा अनुमान है" आपको लगता है कि यह सलाह है कि डिफ़ॉल्ट को बदलना इतना अच्छा विचार नहीं है। क्या आपका मतलब है, जहां भी संभव हो, एक स्पष्ट एन्कोडिंग का उपयोग करें, आपूर्ति किए गए डैफॉल्ट का उपयोग करते समय और कुछ भी संभव नहीं है?
राधावल्द

1
@Raedwald: हाँ, मेरा यही मतलब है। प्लेटफ़ॉर्म डिफ़ॉल्ट एन्कोडिंग (कम से कम एक अंत उपयोगकर्ता मशीन पर) है कि सिस्टम में आमतौर पर उपयोग किए जा रहे लोकल में कौन से उपयोगकर्ता हैं। यदि आप कोई बेहतर (यानी दस्तावेज़-विशिष्ट) जानकारी है, तो आपको जानकारी का उपयोग करना चाहिए।
माइकल बोर्गवर्ड 14

1
@MichaelBorgwardt बकवास। इनपुट एन्कोडिंग को ऑटो-डिटेक्ट करने के लिए लाइब्रेरी का उपयोग करें, और बीओएम के साथ यूनिकोड के रूप में सहेजें। यह एन्कोडिंग नरक से निपटने और लड़ने का एकमात्र तरीका है।
१०:२४

मुझे लगता है कि आप दोनों एक ही पृष्ठ में नहीं हैं। माइकल डिकोडिंग के बारे में बात करता है जबकि राएडवल्ड आप डिकोडिंग के बाद प्रसंस्करण के बारे में बात करते हैं।
पश्चिमीगंज

12

इसे इस्तेमाल करे :

    new OutputStreamWriter( new FileOutputStream("Your_file_fullpath" ),Charset.forName("UTF8"))

5

हम एक ही मुद्दे पर चल रहे थे। हमने इस लेख (और अन्य) से बिना किसी लाभ के कई सुझाव दिए हैं। हमने भी जोड़ने की कोशिश की -Dfile.encoding=UTF8और कुछ भी काम नहीं लग रहा था।

इस समस्या से जूझ रहे लोगों के लिए, निम्नलिखित लेख ने अंत में हमें यह बताने में मदद की कि लोकेल सेटिंग कैसे टूट सकती unicode/UTF-8हैJava/Tomcat

http://www.jvmhost.com/articles/locale-breaks-unicode-utf-8-java-tomcat

~/.bashrcफ़ाइल में सही तरीके से लोकल सेट करना हमारे लिए काम करता है।


4

मैंने बहुत सी चीजों की कोशिश की है, लेकिन यहां का नमूना कोड सही काम करता है। संपर्क

कोड का कूट है:

String s = "एक गाव में एक किसान";
String out = new String(s.getBytes("UTF-8"), "ISO-8859-1");

4

यदि आप स्प्रिंग बूट का उपयोग कर रहे हैं और file.encodingजेवीएम में तर्क पारित करना चाहते हैं तो आपको इसे उसी तरह चलाना होगा:

mvn spring-boot:run -Drun.jvmArguments="-Dfile.encoding=UTF-8"

यह हमारे लिए आवश्यक था क्योंकि हम JTwigटेम्प्लेट का उपयोग कर रहे थे और ऑपरेटिंग सिस्टम था ANSI_X3.4-1968जिसे हमने पायाSystem.out.println(System.getProperty("file.encoding"));

आशा है कि यह किसी की मदद करता है!


2

मैं Amazon (AWS) इलास्टिक बीनस्टॉक का उपयोग कर रहा हूं और इसे सफलतापूर्वक UTF-8 में बदल दिया है।

इलास्टिक बीनस्टॉक में, कॉन्फ़िगरेशन> सॉफ़्टवेयर, "पर्यावरण गुण" पर जाएं। जोड़ें (नाम) JAVA_TOOL_OPTIONS (मान) -Dfile.encoding = UTF8 के साथ

सहेजने के बाद, वातावरण UTF-8 एन्कोडिंग के साथ पुनरारंभ होगा।


1

इस बात पर स्पष्ट नहीं है कि आप क्या करते हैं और इस बिंदु पर नियंत्रण नहीं है। यदि आप एक अलग आउटपुटस्ट्रीम क्लास को गंतव्य फ़ाइल पर इंटर कर सकते हैं, तो आप आउटपुटस्ट्रीम की एक उपप्रकार का उपयोग कर सकते हैं जो स्ट्रट्स को बाइट्स में बदल देता है, जिसे आप परिभाषित करते हैं, डिफ़ॉल्ट रूप से 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

यदि यह दृष्टिकोण संभव नहीं है, तो यदि आप यहां स्पष्ट रूप से स्पष्ट कर सकते हैं कि आप डेटा प्रवाह और निष्पादन पर्यावरण के संदर्भ में क्या कर सकते हैं और इसे नियंत्रित नहीं कर सकते (हालांकि मुझे पता है कि कभी-कभी निर्धारित से अधिक आसान होता है)। सौभाग्य।


5
DataInputStream और DataOutputStream विशेष उद्देश्य वाली कक्षाएं हैं जिनका उपयोग कभी भी सादे पाठ फ़ाइलों के साथ नहीं किया जाना चाहिए। संशोधित UTF-8 वे रोजगार के लिए वास्तविक UTF-8 के साथ संगत नहीं हैं। इसके अलावा, अगर ओपी आपके समाधान का उपयोग कर सकता है, तो वह इस काम के लिए सही उपकरण का उपयोग भी कर सकता है: एक आउटपुटस्ट्रीमराइटर।
एलन मूर

1
mvn clean install -Dfile.encoding=UTF-8 -Dmaven.repo.local=/path-to-m2

कमांड ने निष्पादन-मावेन-प्लगइन के साथ काम किया, ताकि जेनकिंस कार्य को कॉन्फ़िगर करते समय त्रुटि का समाधान हो सके।

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)

0

हम वहाँ दो सिस्टम गुण एक साथ सेट करते हैं और यह सिस्टम को सब कुछ utf8 में ले जाता है

file.encoding=UTF8
client.encoding.overrideUTF-8

7
Client.encoding.override गुण WebSphere विशिष्ट प्रतीत होता है।
क्रिस्टोफ रूसो

0

स्वीकृत उत्तर पर @ कस्पार टिप्पणी के बाद, सूर्य के अनुसार इसे ठीक करने का पसंदीदा तरीका है:

"अपना जावा प्रोग्राम शुरू करने से पहले अंतर्निहित प्लेटफ़ॉर्म के स्थान को बदलें।"

http://bugs.java.com/view_bug.do?bug_id=4163515

देखने वाले के लिए:

http://jaredmarkell.com/docker-and-locales/


0

हाल ही में मैं एक स्थानीय कंपनी के नोट्स 6.5 सिस्टम में टकरा गया और पता चला कि वेबमेल एक गैर-ज़ोन्वेन लोकल विंडोज इंस्टॉलेशन पर अज्ञात अक्षर दिखाएगा। ऑनलाइन कई हफ्तों के लिए खोदा है, यह कुछ ही मिनटों पहले लगा:

जावा गुणों में, निम्न स्ट्रिंग को रनटाइम पैरामीटर में जोड़ें

-Dfile.encoding=MS950 -Duser.language=zh -Duser.country=TW -Dsun.jnu.encoding=MS950

UTF-8 सेटिंग इस मामले में काम नहीं करेगी।


0

मेरी टीम को विंडोज़ के साथ मशीनों में एक ही मुद्दे का सामना करना पड़ा .. फिर इसे दो तरीकों से हल करने में कामयाब रहे:

a) एनवायरमेंट वैरिएबल (यहां तक ​​कि विंडोज सिस्टम प्रेफरेंस में) सेट करें

JAVA_TOOL_OPTIONS
-Dfile.encoding = UTF8

ख) अपने pom.xml में स्निपेट का पालन करें:

 -Dfile.encoding=UTF-8 

भीतर

 <jvmArguments>
 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001
 -Dfile.encoding=UTF-8
 </jvmArguments>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.