जावा में UTF8 बाइट सरणियों से स्ट्रिंग्स को और कैसे परिवर्तित करें


239

जावा में, मेरे पास एक स्ट्रिंग है और मैं इसे बाइट सरणी (UTF8 में, या कुछ अन्य एन्कोडिंग) के रूप में एन्कोड करना चाहता हूं। वैकल्पिक रूप से, मेरे पास एक बाइट सरणी है (कुछ ज्ञात एन्कोडिंग में) और मैं इसे जावा स्ट्रिंग में बदलना चाहता हूं। मैं ये रूपांतरण कैसे करूँ?

जवाबों:


355

स्ट्रिंग से बाइट में परिवर्तित करें []:

String s = "some text here";
byte[] b = s.getBytes(StandardCharsets.UTF_8);

बाइट से [] स्ट्रिंग में परिवर्तित करें:

byte[] b = {(byte) 99, (byte)97, (byte)116};
String s = new String(b, StandardCharsets.US_ASCII);

आपको निश्चित रूप से सही एन्कोडिंग नाम का उपयोग करना चाहिए। मेरे उदाहरणों में US-ASCII और UTF-8, दो सबसे आम एनकोडिंग का उपयोग किया गया।


30
यूएस-एएससीआईआई वास्तव में आजकल बहुत आम एन्कोडिंग नहीं है। Windows-1252 और ISO-8859-1 (जो ASCII के सुपरसेट हैं) कहीं अधिक व्यापक हैं।
माइकल बोर्गवर्ड

11
वास्तव में, मुझे यह अपने काम में काफी सामान्य लगता है। मैं अक्सर बाइट्स की धाराएँ पढ़ता हूँ जो शायद विंडोज़ -1252 या ISO-8859-1 या यहाँ तक कि "उस विरासत कार्यक्रम का उत्पादन जो हमने पिछले 10 वर्षों से किया है" के रूप में सहेजा गया है, लेकिन जिसमें बाइट्स वैध होने की गारंटी है यूएस-एएससीआईआई अक्षर। मुझे अक्सर ऐसी फ़ाइलों को जेनरेट करने की भी आवश्यकता होती है (कोड द्वारा खपत के लिए जो गैर-एएससीआईआई पात्रों को संभालने में सक्षम हो सकती है या नहीं। मूल रूप से, यूएस-एएससीआईआई सॉफ्टवेयर के कई टुकड़ों का "सबसे बड़ा सामान्य भाजक" है।
mcherm

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

7
@ स्पेसर क्योंकि डॉक्स फॉर चरसेट लिस्ट "UTF-8" एक मानक वर्णमाला के रूप में है। मेरा मानना ​​है कि आपकी स्पेलिंग भी स्वीकार की जाती है, लेकिन मैंने डॉक्स के साथ कहा।
mcherm

20
JDK7 के बाद से आप StandardCharsets.UTF_8 docs.oracle.com/javase/7/docs/api/java/nio/charset/…
Rafel Membrives

95

यहाँ एक समाधान है जो हर रूपांतरण के लिए चारसेट लुकअप करने से बचता है:

import java.nio.charset.Charset;

private final Charset UTF8_CHARSET = Charset.forName("UTF-8");

String decodeUTF8(byte[] bytes) {
    return new String(bytes, UTF8_CHARSET);
}

byte[] encodeUTF8(String string) {
    return string.getBytes(UTF8_CHARSET);
}

4
@mcherm: भले ही प्रदर्शन अंतर छोटा हो, मैं संभव होने पर उनके स्ट्रिंग रूपों में ऑब्जेक्ट्स (चारसेट, URL, आदि) का उपयोग करना पसंद करता हूं।
बार्ट वैन ह्युकेलोम

7
नोट: "१.६ के बाद से" सार्वजनिक स्ट्रिंग (बाइट [] बाइट्स, चार्सेट चारसेट)
लेओ

1
"हर रूपांतरण के लिए चारसेट लुकअप करने से बचा जाता है" के बारे में ... कृपया कुछ स्रोत का हवाला दें। Java.nio.charset.Charset String.getBytes के शीर्ष पर नहीं बनाया गया है और इसलिए String.getBytes से अधिक ओवरहेड है?
पचेरियर

2
डॉक्स यह बताता है: "इस पद्धति का व्यवहार जब इस स्ट्रिंग को दिए गए वर्णक्रम में एन्कोड नहीं किया जा सकता है तो अनिर्दिष्ट है। एन्कोडिंग प्रक्रिया पर अधिक नियंत्रण की आवश्यकता होने पर चारसेटएन्कोडर वर्ग का उपयोग किया जाना चाहिए।"
पेइगो

24
नोट: जावा 1.7 के बाद से, आप StandardCharsets.UTF_8UTF-8 चारसेट तक पहुंचने के निरंतर तरीके के लिए उपयोग कर सकते हैं ।
कैट

17
String original = "hello world";
byte[] utf8Bytes = original.getBytes("UTF-8");

धन्यवाद! मैंने इसे फिर से लिखा और रूपांतरण की दूसरी दिशा जोड़ दी।
mcherm

1
@smink वैकल्पिक में पानी का छींटा। इसे "UTF-8" का उपयोग करना चाहिए
मेल निकोलसन

14

आप सीधे स्ट्रिंग (बाइट [], स्ट्रिंग) कंस्ट्रक्टर और getBytes (स्ट्रिंग) विधि के माध्यम से परिवर्तित कर सकते हैं । जावा वर्णसेट वर्ग के माध्यम से उपलब्ध चरित्र सेटों को उजागर करता है । JDK प्रलेखन सूचियों ने एनकोडिंग का समर्थन किया

90% समय, इस तरह के रूपांतरण धाराओं पर किए जाते हैं, इसलिए आप रीडर / राइटर कक्षाओं का उपयोग करेंगे । आप मनमाने ढंग से बाइट धाराओं पर स्ट्रिंग के तरीकों का उपयोग करते हुए आकस्मिक रूप से डिकोड नहीं करेंगे - आप अपने आप को मल्टीबीट पात्रों से जुड़े बगों के लिए खुला छोड़ देंगे।


क्या आप विस्तार से समझा सकते हैं? यदि मेरा आवेदन एन्कोड करता है और स्ट्रिंग्स को अंदर करता है UTF-8, तो मल्टीबाइट्स पात्रों के बारे में क्या चिंता है?
राफियन

यदि आप एक बार में सभी वर्ण डेटा को रूपांतरित नहीं करते हैं, तो @ समस्याएँ उत्पन्न हो सकती हैं। एक उदाहरण के लिए यहाँ देखें ।
मैकडॉवेल

12

मेरा tomcat7 कार्यान्वयन ISO-8859-1 के रूप में तार को स्वीकार कर रहा है; HTTP अनुरोध के सामग्री-प्रकार के बावजूद। 'É' जैसे पात्रों की सही ढंग से व्याख्या करने की कोशिश करते समय निम्न समाधान ने मेरे लिए काम किया।

byte[] b1 = szP1.getBytes("ISO-8859-1");
System.out.println(b1.toString());

String szUT8 = new String(b1, "UTF-8");
System.out.println(szUT8);

जब US-ASCII के रूप में स्ट्रिंग की व्याख्या करने की कोशिश की जा रही है, तो बाइट जानकारी की सही व्याख्या नहीं की गई थी।

b1 = szP1.getBytes("US-ASCII");
System.out.println(b1.toString());

8
FYI करें, जावा 7 के रूप में आप उन चारसेट नामों के लिए स्थिरांक का उपयोग कर सकते हैं जैसे कि StandardCharSets.UTF_8और StandardCharSets.ISO_8859_1
बेसिल बॉर्क

मेरे दिन को बचाया, ऊपर उल्लिखित पहले समाधान के लिए बिल्कुल ठीक काम कर रहा है।
हसन जमील

7

एक विकल्प के रूप में, अपाचे कॉमन्स से स्ट्रिंगरूटिल्स का उपयोग किया जा सकता है।

 byte[] bytes = {(byte) 1};
 String convertedString = StringUtils.newStringUtf8(bytes);

या

 String myString = "example";
 byte[] convertedBytes = StringUtils.getBytesUtf8(myString);

यदि आपके पास गैर-मानक charset है, तो आप तदनुसार getBytesUnchecked () या newString () का उपयोग कर सकते हैं ।


4
ध्यान दें कि यह StringUtils Commons Codec से है , Commons Lang से नहीं।
Arend v। Reinersdorff

हाँ, एक बिटचा! ग्रैडल के लिए, मावेन उपयोगकर्ताओं: "कॉमन्स-कोडेक: कॉमन्स-कोडेक: 1.10" (लेखन के समय)। यह भी उदाहरण के लिए Apache POI के साथ निर्भरता के रूप में बंडल में आता है। इसके अलावा बचाव के लिए अपाचे कॉमन्स, हमेशा की तरह!
माईक कृंतक

2

एक सामान्य स्ट्रिंग संदेश को बाइट्स की एक श्रृंखला को डिकोड करने के लिए, मुझे अंततः इस कोड के साथ UTF-8 एन्कोडिंग के साथ काम करना पड़ा:

/* Convert a list of UTF-8 numbers to a normal String
 * Usefull for decoding a jms message that is delivered as a sequence of bytes instead of plain text
 */
public String convertUtf8NumbersToString(String[] numbers){
    int length = numbers.length;
    byte[] data = new byte[length];

    for(int i = 0; i< length; i++){
        data[i] = Byte.parseByte(numbers[i]);
    }
    return new String(data, Charset.forName("UTF-8"));
}

1

यदि आप 7-बिट ASCII या ISO-8859-1 (आश्चर्यजनक रूप से सामान्य प्रारूप) का उपयोग कर रहे हैं, तो आपको एक नया java.lang.String बनाने की आवश्यकता नहीं है । यह बहुत अधिक प्रदर्शन करने के लिए बस बाइट चार में डाली है:

पूर्ण कार्य उदाहरण:

for (byte b : new byte[] { 43, 45, (byte) 215, (byte) 247 }) {
    char c = (char) b;
    System.out.print(c);
}

यदि आप you , Å, extended, extended, not, Ê जैसे विस्तारित वर्णों का उपयोग नहीं कर रहे हैं और यह सुनिश्चित कर सकते हैं कि केवल संचरित मूल्य पहले 128 यूनिकोड वर्णों के हैं, तो यह कोड UTF-8 और विस्तारित ASCII के लिए भी काम करेगा। (cp-1252 की तरह)।


1

मैं टिप्पणी नहीं कर सकता लेकिन एक नया सूत्र शुरू नहीं करना चाहता। लेकिन यह काम नहीं कर रहा है। एक साधारण दौर की यात्रा:

byte[] b = new byte[]{ 0, 0, 0, -127 };  // 0x00000081
String s = new String(b,StandardCharsets.UTF_8); // UTF8 = 0x0000, 0x0000,  0x0000, 0xfffd
b = s.getBytes(StandardCharsets.UTF_8); // [0, 0, 0, -17, -65, -67] 0x000000efbfbd != 0x00000081

मुझे बी [] एन्कोडिंग से पहले और बाद में वही सरणी चाहिए जो यह नहीं है (यह पहले उत्तर के लिए संदर्भित है)।


0
//query is your json   

 DefaultHttpClient httpClient = new DefaultHttpClient();
 HttpPost postRequest = new HttpPost("http://my.site/test/v1/product/search?qy=");

 StringEntity input = new StringEntity(query, "UTF-8");
 input.setContentType("application/json");
 postRequest.setEntity(input);   
 HttpResponse response=response = httpClient.execute(postRequest);

स्ट्रिंग एंटिटी 'क्वेरी' को utf-8 में परिवर्तित करता है या केवल इकाई संलग्न करते समय याद रखता है?
SyntaxRules



-9

बहुत देर से लेकिन मुझे अभी इस मुद्दे का सामना करना पड़ा है और यह मेरा फिक्स है:

private static String removeNonUtf8CompliantCharacters( final String inString ) {
    if (null == inString ) return null;
    byte[] byteArr = inString.getBytes();
    for ( int i=0; i < byteArr.length; i++ ) {
        byte ch= byteArr[i]; 
        // remove any characters outside the valid UTF-8 range as well as all control characters
        // except tabs and new lines
        if ( !( (ch > 31 && ch < 253 ) || ch == '\t' || ch == '\n' || ch == '\r') ) {
            byteArr[i]=' ';
        }
    }
    return new String( byteArr );
}

2
सबसे पहले, यह रूपांतरण नहीं है: यह गैर-मुद्रण योग्य बाइट्स को हटाने है। दूसरा, यह मानता है कि अंतर्निहित OS की डिफ़ॉल्ट एन्कोडिंग वास्तव में मुद्रण योग्य वर्णों के लिए ASCII पर आधारित है (उदाहरण के लिए, EBCDIC का उपयोग करके आईबीएम मेनफ्रेम पर काम नहीं करेगा)।
इसहाक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.