বাইট অ্যারে স্ট্রিং (জাভা) এ রূপান্তর করা হচ্ছে


85

আমি গুগল অ্যাপ ইঞ্জিনে একটি ওয়েব অ্যাপ্লিকেশন লিখছি। এটি লোকেদের মূলত এইচটিএমএল কোড সম্পাদনা করতে দেয় .htmlযা ব্লুবস্টোরে একটি ফাইল হিসাবে সঞ্চিত হয় ।

আমি byte[]ফাইলে সমস্ত অক্ষরের একটি ফিরিয়ে আনার জন্য ফেচডেটা ব্যবহার করছি । আমি এইচটিএমএল প্রিন্ট করার চেষ্টা করছি যাতে ব্যবহারকারী এইচটিএমএল কোড সম্পাদনা করতে পারেন। সবকিছু দুর্দান্ত কাজ করে!

এখানে এখন আমার একমাত্র সমস্যা:

কোনও স্ট্রিংয়ে ফিরে রূপান্তর করার সময় বাইট অ্যারেতে কিছু সমস্যা রয়েছে। স্মার্ট কোটস এবং বেশ কয়েকটি চরিত্র ছদ্মবেশপূর্ণ দেখাচ্ছে। (? এর বা জাপানি প্রতীক ইত্যাদি) বিশেষত এটি বেশ কয়েকটি বাইট যা আমি দেখছি তাতে নেতিবাচক মান রয়েছে যা সমস্যা সৃষ্টি করছে।

স্মার্ট উক্তিগুলি বাইট অ্যারে হিসাবে -108এবং ফিরে আসছে -109। কেন এটি এবং আমি সঠিক চরিত্রের এনকোডিংটি দেখানোর জন্য নেতিবাচক বাইটগুলি ডিকোড করতে পারি?



হাই, আমি জানি এটি সত্যিই একটি পুরানো পোস্ট তবে আমি একই ধরণের সমস্যার মুখোমুখি। আমি এসএসএল-এর জন্য একটি ম্যান-ইন-মধ্য-প্রক্সি তৈরি করছি। আমি যে সমস্যার মুখোমুখি হচ্ছি তাও আপনার মতই। আমি সকেট শুনি এবং ডেটা InputStreamএবং তারপরে byte[]। এখন যখন আমি স্ট্রিংয়ে রূপান্তর করার চেষ্টা করছি byte[](আক্রমণগুলির জন্য আমার প্রতিক্রিয়া বডিটি ব্যবহার করা প্রয়োজন), আমি স্মার্ট উদ্ধৃতি এবং প্রশ্ন চিহ্নগুলি এবং কী না তা পূর্ণ সত্যই মজার চরিত্রগুলি পাই। আমি বিশ্বাস করি পুলিশের সমস্যা খনি হিসাবে একই হিসাবে আমরা উভয় সঙ্গে তার আচরণ করা হয় htmlমধ্যে byte[]। আপনি দয়া করে পরামর্শ করতে পারেন?
পারুল এস

যাইহোক, আমি সীমাতে.প্রোপার্টি ব্যবহার করে আমার সিস্টেমের এনকোডিং সন্ধান করতে পেরেছি এবং এটি "সিপি 1252" হিসাবে পেয়েছি। এখন, আমি ব্যবহার করেছি String str=new String(buffer, "Cp1252");তবে কোনও সাহায্য নেই।
পারুল এস

উত্তর:


141

বাইট অ্যারেটিতে একটি বিশেষ এনকোডিংয়ের অক্ষর রয়েছে (যা আপনার জানা উচিত)। এটিকে স্ট্রিংয়ে রূপান্তর করার উপায় হ'ল:

String decoded = new String(bytes, "UTF-8");  // example for one encoding type

দ্য ওয়ে - কাঁচা বাইটগুলি প্রদর্শিত হবে নেতিবাচক দশমিক হিসাবে প্রদর্শিত হতে পারে কারণ জাভা ডাটাটাইপ byteস্বাক্ষরিত হয়েছে, এটি -128 থেকে 127 এর মধ্যে রয়েছে covers


-109 = 0x93: Control Code "Set Transmit State"

মান (-109) ইউনিকোডের একটি মুদ্রণযোগ্য নিয়ন্ত্রণের অক্ষর। সুতরাং ইউটিএফ -8 এই অক্ষর প্রবাহের জন্য সঠিক এনকোডিং নয়।

0x93"উইন্ডোজ -১২২২" তে আপনি যে "স্মার্ট উক্তি" সন্ধান করছেন তা হ'ল সেই এনকোডিংয়ের জাভা নামটি "সিপি 1252"। পরের লাইনটি একটি পরীক্ষার কোড সরবরাহ করে:

System.out.println(new String(new byte[]{-109}, "Cp1252")); 

4
আমি ইউটিএফ -8 ব্যবহার করার চেষ্টা করেছি এবং এটি এখনও? এর হিসাবে প্রকাশিত হয়েছে। কীভাবে এটি ?ণাত্মক মানগুলির জন্য কোনও ম্যাপিং খুঁজে পাচ্ছে না?
জোশ

0x93 ইউটিএফ -8 এ একটি বৈধ ধারাবাহিকতা বাইট, যদিও - এই বাইট উপস্থিতি কেবল এটির ইউটিএফ -8 হওয়ার বিধান দেয় যদি এটি প্রথম দুটি বিট সেট সহ বাইট পরে আসে না।
নিক জনসন

4
@ জোশ আন্দ্রেয়াস ব্যাখ্যা করেছেন কেন - কারণ জাভার byteডেটাটাইপ স্বাক্ষরিত। 'নেতিবাচক' মানগুলি সর্বাধিক উল্লেখযোগ্য বাইট সেট সহ বাইট। আপনার সম্ভবত ব্যবহার করা উচিত সবচেয়ে বেশি চরিত্রের সেটটি হ'ল - উইন্ডোজ -১২২২। অনুমান বা কনভেনশন থেকে কোন চরিত্রটি সেট করতে হবে তা আপনার জানা উচিত, যদিও অনুমান না করেই।
নিক জনসন

25

জাভা 7 এবং উপরে

আপনি স্ট্যান্ডার্ডচরেটস থেকে ধ্রুবক Stringহিসাবে আপনার পছন্দসই এনকোডিংটি কনস্ট্রাক্টরের কাছেও দিতে পারেন । এটি অন্যান্য হিসাবে দেওয়া এনকোডিংটি পাস করার চেয়ে নিরাপদ হতে পারে ।CharsetString

উদাহরণস্বরূপ, ইউটিএফ -8 এনকোডিংয়ের জন্য

String bytesAsString = new String(bytes, StandardCharsets.UTF_8);

4
এই থেকে 2011 -1 উত্তর পুনরাবৃত্তি হয়
james.garriss

4
@ জেমস.গরিসগুলি আমি মনে করি না, যদিও আমি জাভা in-তে প্রবর্তিত নতুন কন্সট্রাক্টরের কথা উল্লেখ করছি যাতে এনকোডিংটি একটি ধ্রুবক হিসাবে পাস হতে পারে, যা আমার মতে আগের অ্যাপির তুলনায় সুন্দর এবং নিরাপদ 7 আগের উত্তরগুলিতে উল্লিখিত ছিল যেখানে এনকোডিংটি স্ট্রিং হিসাবে পাস করা হয়েছে, যদি তা না হয়।
davnicwil


5
public class Main {

    /**
     * Example method for converting a byte to a String.
     */
    public void convertByteToString() {

        byte b = 65;

        //Using the static toString method of the Byte class
        System.out.println(Byte.toString(b));

        //Using simple concatenation with an empty String
        System.out.println(b + "");

        //Creating a byte array and passing it to the String constructor
        System.out.println(new String(new byte[] {b}));

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Main().convertByteToString();
    }
}

আউটপুট

65
65
A

5
public static String readFile(String fn)   throws IOException 
{
    File f = new File(fn);

    byte[] buffer = new byte[(int)f.length()];
    FileInputStream is = new FileInputStream(fn);
    is.read(buffer);
    is.close();

    return  new String(buffer, "UTF-8"); // use desired encoding
}

4
এই কোডটি যদি readকোনও ব্যতিক্রম ছুঁড়ে দেয় তবে কোনও সংস্থান ফাঁস করবে will
রায়েডওয়াল্ড

4

আমার পরামর্শ Arrays.toString(byte_array);

এটি আপনার উদ্দেশ্য উপর নির্ভর করে। উদাহরণস্বরূপ, আমি একটি বাইট অ্যারের সংরক্ষণ করতে চেয়েছিলাম ঠিক একই বিন্যাসের সময় আপনি ডিবাগের সময় দেখতে পেলেন এমন বিন্যাসের মতো: [1, 2, 3]আপনি যদি বাইটকে অক্ষর বিন্যাসে রূপান্তর না করে ঠিক একই মান সংরক্ষণ করতে চান তবে এটি করুন , Arrays.toString (byte_array). তবে আপনি যদি বাইটের পরিবর্তে অক্ষরগুলি সংরক্ষণ করতে চান তবে আপনার ব্যবহার করা উচিত String s = new String(byte_array)। এই ক্ষেত্রে, অক্ষরের বিন্যাসের sসমতুল্য [1, 2, 3]


আপনি কেন এটি প্রস্তাব দিচ্ছেন সে সম্পর্কে আপনি আরও তথ্য দিতে পারেন? (এটি সমস্যার সমাধান করবে? আপনি কেন এটি সমাধান করেন বলতে পারেন?) ধন্যবাদ!
ডিন জে

এটি আপনার উদ্দেশ্য উপর নির্ভর করে। উদাহরণস্বরূপ, আমি কোনও বাইট অ্যারের সংরক্ষণ করতে চেয়েছিলাম ঠিক একই ধরণের ডিবাগ করার সময় আপনি দেখতে যে ফর্ম্যাটটি দেখতে পান: [1, 2, 3] আপনি যদি বাইটকে অক্ষর বিন্যাসে রূপান্তর না করে ঠিক একই মান সংরক্ষণ করতে চান, অ্যারে.টো স্ট্রিং (বাইট_আরে) এটি করে ,. তবে আপনি যদি বাইটের পরিবর্তে অক্ষর সংরক্ষণ করতে চান তবে আপনার স্ট্রিং s = নতুন স্ট্রিং (বাইট_আরে) ব্যবহার করা উচিত। এই ক্ষেত্রে, s এর সমতুল্য [1, 2, 3] অক্ষরের আকারে।
প্রশ্নকর্তা

@ এস, আপনার নিজের মন্তব্যে মন্তব্য না করে নিজের উত্তরটিতে (এটি সম্পাদনা করে) এই তথ্য যুক্ত করা উচিত। সাধারণত তাই আপনার সর্বদা মনে রাখা উচিত যে মন্তব্যগুলি যে কোনও সময়ে মুছে ফেলা হতে পারে - সত্যই গুরুত্বপূর্ণ তথ্যটি উত্তরে থাকা উচিত।
জিন ব্রুকস্ট্রা

3

Andreas_D এর আগের উত্তরটি ভাল। আমি কেবল যুক্ত করতে যাচ্ছি আপনি যেখানেই আউটপুট প্রদর্শন করছেন সেখানে একটি ফন্ট এবং একটি অক্ষর এনকোডিং থাকবে এবং এটি কিছু অক্ষরকে সমর্থন নাও করতে পারে।

এটি জাভা বা আপনার ডিসপ্লে যা সমস্যা সে বিষয়ে কাজ করার জন্য এটি করুন:

    for(int i=0;i<str.length();i++) {
        char ch = str.charAt(i);
        System.out.println(i+" : "+ch+" "+Integer.toHexString(ch)+((ch=='\ufffd') ? " Unknown character" : ""));
    }

জাভা কোনও অক্ষর ম্যাপ করবে যা এটি অজানা অক্ষরের জন্য অফিসিয়াল অক্ষর 0xfffd তে বুঝতে পারে না। আপনি একটি দেখুন '?' আউটপুটটিতে, তবে এটি 0xfffd তে ম্যাপ করা হয়নি, এটি আপনার ডিসপ্লে ফন্ট বা এনকোডিং যা সমস্যা, জাভা নয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.