জাভাতে ইউটিএফ 8 বাইট অ্যারে থেকে স্ট্রিংগুলি কীভাবে রূপান্তর করতে হয়


239

জাভাতে, আমার কাছে একটি স্ট্রিং রয়েছে এবং আমি এটিকে বাইট অ্যারে (ইউটিএফ 8 বা অন্য কোনও এনকোডিংয়ে) হিসাবে এনকোড করতে চাই। পর্যায়ক্রমে, আমার একটি বাইট অ্যারে আছে (কিছু পরিচিত এনকোডিংয়ে) এবং আমি এটি একটি জাভা স্ট্রিংয়ে রূপান্তর করতে চাই। আমি এই রূপান্তরগুলি কীভাবে করব?

উত্তর:


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

আপনার অবশ্যই অবশ্যই সঠিক এনকোডিংয়ের নামটি ব্যবহার করা উচিত। আমার উদাহরণগুলি ইউএস-এএসসিআইআই এবং ইউটিএফ -8 ব্যবহার করেছে, দুটি সবচেয়ে সাধারণ এনকোডিং।


30
ইউএস-এএসসিআইআই আসলে আজকাল খুব সাধারণ এনকোডিং নয়। উইন্ডোজ -1222 এবং আইএসও -8859-1 (যা এএসসিআইআইয়ের সুপারপেট) এটি আরও বেশি বিস্তৃত।
মাইকেল বার্গওয়ার্ট 13

11
আসলে, আমি আমার কাজ এটি মোটামুটি সাধারণ বলে মনে করি। আমি প্রায়শই বাইটের স্ট্রিমগুলি পড়ে থাকি যা উইন্ডোজ -১২২২ বা আইএসও -৮85৮৯-১ বা এমনকি "গত দশ বছর ধরে আমাদের সেই উত্তরাধিকারসূত্রে প্রোগ্রামের আউটপুট" হিসাবে সংরক্ষণ করা হয়েছিল, তবে এতে বাইটস সহ বৈধ হওয়ার নিশ্চয়তা রয়েছে US-ASCII অক্ষর। আমার প্রায়শই এই জাতীয় ফাইলগুলি জেনারেট করার প্রয়োজন হয় (কোড অনুসারে ব্যবহারের জন্য যা অ-এসসিআইআই অক্ষরগুলি পরিচালনা করতে পারে বা নাও করতে পারে Bas মূলত, ইউএস-এএসসিআইই সফটওয়্যারটির অনেকগুলি অংশের "বৃহত্তম সাধারণ ডিনামিনেটর")।
মাচারম 18

1
এই পদ্ধতিটি তবে রূপান্তরটিতে কোনও সমস্যার প্রতিবেদন করবে না। এটি আপনি যা চান তা হতে পারে। যদি তা না হয় তবে তার পরিবর্তে চরসেটইনকডার ব্যবহার করার পরামর্শ দেওয়া হচ্ছে।
মাইকেল পিফেল

7
@ পেসারিয়র কারণ চারসেটের জন্য ডক্সগুলি "ইউটিএফ -8" স্ট্যান্ডার্ড অক্ষরগুলির একটি হিসাবে তালিকাবদ্ধ করে । আমি বিশ্বাস করি যে আপনার বানানটিও মেনে নেওয়া হয়েছে তবে ডক্স যা বলেছিল তা দিয়েই গিয়েছিলাম।
মাচারেম


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
@ মাচারম: পারফরম্যান্সের পার্থক্য ছোট হলেও, আমি যখন সম্ভব তখন তাদের স্ট্রিং ফর্মগুলির চেয়ে অবজেক্ট (চারসেট, ইউআরএল, ইত্যাদি) ব্যবহার পছন্দ করি।
বার্ট ভ্যান হিউকেলোম

7
দ্রষ্টব্য: "যেহেতু 1.6" পাবলিক স্ট্রিং (বাইট [] বাইটস, চারসেট চরসেট)
লিও

1
"প্রতিটি রূপান্তরটির জন্য চরসেট লুকোচুরি সম্পাদন করা এড়ানো" সম্পর্কিত বিষয়ে ... দয়া করে কোনও উত্স উদ্ধৃত করুন। Java.nio.charset.Charset স্ট্রিং.জেটবাইটসের শীর্ষে নির্মিত নয় এবং তাই স্ট্রিং.জেটবাইটসের চেয়ে বেশি ওভারহেড রয়েছে?
পেসারিয়ার

2
দস্তাবেজগুলি জানিয়েছে: "প্রদত্ত চারসেটে এই স্ট্রিংটি এনকোড করা যায় না যখন এই পদ্ধতির আচরণ অনির্দিষ্ট।
পাইয়েগো

24
দ্রষ্টব্য: জাভা 1.7 সাল থেকে আপনি StandardCharsets.UTF_8ইউটিএফ -8 চারসেট অ্যাক্সেসের অবিচ্ছিন্ন উপায়ের জন্য ব্যবহার করতে পারেন ।
কেট

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

ধন্যবাদ! আমি রূপান্তরটির অন্য দিকটি নিজে যুক্ত করে আবার লিখেছিলাম।
মাচারেম

1
@ স্মিঙ্ক ড্যাশটি dচ্ছিক নয়। এটি "UTF-8" ব্যবহার করা উচিত
মেল নিকোলসন

14

আপনি স্ট্রিং (বাইট [], স্ট্রিং) কনস্ট্রাক্টর এবং গেটবাইটস (স্ট্রিং) পদ্ধতির মাধ্যমে সরাসরি রূপান্তর করতে পারেন । জাভা চরসেট ক্লাসের মাধ্যমে উপলভ্য অক্ষরের সেটগুলি প্রকাশ করে । জেডিকে ডকুমেন্টেশন সমর্থিত এনকোডিংগুলির তালিকা করে

90% সময়, এই জাতীয় রূপান্তরগুলি স্ট্রিমগুলিতে সঞ্চালিত হয়, তাই আপনি পাঠক / লেখক শ্রেণি ব্যবহার করবেন । আপনি স্বেচ্ছাসেবী বাইট স্ট্রিমগুলিতে স্ট্রিং পদ্ধতিগুলি ব্যবহার করে ক্রমবর্ধমানভাবে ডিকোড করবেন না - আপনি মাল্টিবাইট অক্ষরগুলির সাথে জড়িত বাগগুলিতে নিজেকে খোলা রাখবেন।


তুমি কি বিস্তারিত বলতে পারো? যদি আমার অ্যাপ্লিকেশনটি এনকোড করে স্ট্রিংগুলি UTF-8ডিকোড করে তবে মাল্টিবাইট অক্ষর সম্পর্কিত উদ্বেগ কী?
রাফিয়ান

আপনি যদি একসাথে সমস্ত চরিত্রের ডেটা রূপান্তর না করেন তবে @ ইরফিয়ান সমস্যা দেখা দিতে পারে। একটি উদাহরণের জন্য এখানে দেখুন ।
ম্যাকডোয়েল

12

আমার টমক্যাট 7 প্রয়োগটি আইএসও -8859-1 হিসাবে স্ট্রিং গ্রহণ করছে; এইচটিটিপি অনুরোধের সামগ্রী-ধরণের সত্ত্বেও। 'É' এর মতো অক্ষরগুলি সঠিকভাবে ব্যাখ্যা করার চেষ্টা করার সময় নিম্নলিখিত সমাধানটি আমার পক্ষে কাজ করেছিল।

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

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

স্ট্রিংটিকে ইউএস-এএসসিআইআই হিসাবে ব্যাখ্যা করার চেষ্টা করার সময়, বাইট তথ্যটি সঠিকভাবে ব্যাখ্যা করা যায় নি।

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

8
এফওয়াইআই, জাভা 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);

আপনার যদি অ-মানক অক্ষর রয়েছে , আপনি সেই অনুযায়ী getBytesUnchecked () বা newString () ব্যবহার করতে পারেন ।


4
নোট করুন যে কমন্স ল্যাং নয়, কমন্স কোডেকের এই স্ট্রিংটিলগুলি ।
আরেন্দ বনাম রেইনসর্ডফ

হ্যাঁ, কিছুটা গোটচা! গ্রেডল, মাভেন ব্যবহারকারীদের জন্য: "কমন্স-কোডেক: কমন্স-কোডেক: 1.10" (লেখার সময়)। উদাহরণস্বরূপ এটি অ্যাপাচি পিওআইয়ের সাথে নির্ভরতা হিসাবেও বান্ডিল হয়ে আসে। সেই অ্যাপাচি কমন্স ছাড়াও এখনকার মতো!
মাইকে রডেন্ট

2

একটি সাধারণ স্ট্রিং বার্তায় ধারাবাহিক বাইটগুলি ডিকোড করার জন্য অবশেষে আমি এই কোডটির সাথে ইউটিএফ -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 বা আইএসও -8859-1 (একটি আশ্চর্যরকম সাধারণ ফর্ম্যাট) ব্যবহার করে থাকেন তবে আপনাকে কোনও নতুন জাভা.এল.আং স্ট্রিং তৈরি করতে হবে না । বাইটটিকে চরে কেবল কাস্ট করা আরও অনেক বেশি পারফরম্যান্স:

সম্পূর্ণ কাজের উদাহরণ:

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

আপনি যদি extended , Æ, Å, Ç, Ï, like এর মতো প্রসারিত-অক্ষর ব্যবহার না করে থাকেন এবং নিশ্চিত হয়ে যেতে পারেন যে কেবলমাত্র 128 ইউনিকোড অক্ষর দ্বারা প্রেরিত মানগুলি হয় তবে এই কোডটি ইউটিএফ -8 এবং বর্ধিত এএসসিআইআইয়ের জন্যও কাজ করবে (সিপি-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 এ রূপান্তর করে বা সত্তা সংযুক্ত করার জন্য কেবল মনে রাখে?
সিনট্যাক্স রুলস



-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
প্রথমত, এটি কোনও রূপান্তর নয়: এটি মুদ্রণযোগ্য বাইটগুলি অপসারণ করা। দ্বিতীয়ত, এটি ধরে নেওয়া হয় যে অন্তর্নিহিত ওএসের ডিফল্ট এনকোডিংটি প্রিন্টযোগ্য অক্ষরগুলির জন্য ASCII এর উপর ভিত্তি করে রয়েছে (উদাহরণস্বরূপ, আইবিএম মেইনফ্রেমে EBCDIC ব্যবহার করে কাজ করবে না)।
ইসহাক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.