জাভা: কীভাবে কোনও স্ট্রিমের সঠিক চরসেট এনকোডিং নির্ধারণ করবেন


140

নিম্নলিখিত থ্রেডের রেফারেন্স সহ: জাভা অ্যাপ্লিকেশন: আইসো -8859-1 এনকোডযুক্ত ফাইলটি সঠিকভাবে পড়তে অক্ষম

ইনপুটস্ট্রিম / ফাইলের সঠিক চরসেট এনকোডিংটি অগ্রগতিগতভাবে নির্ধারণ করার সেরা উপায় কী?

আমি নিম্নলিখিত ব্যবহার করে চেষ্টা করেছি:

File in =  new File(args[0]);
InputStreamReader r = new InputStreamReader(new FileInputStream(in));
System.out.println(r.getEncoding());

তবে আমি যে ফাইলটি ISO8859_1 এর সাথে এনকোড করা জানি তার উপরের কোডটি ASCII দেয়, যা সঠিক নয় এবং আমাকে ফাইলের সামগ্রীটি সঠিকভাবে কনসোলে রেন্ডার করতে দেয় না।


11
এডুয়ার্ড ঠিক আছে, "আপনি একটি স্বেচ্ছাসেবী বাইট স্ট্রিমের এনকোডিং নির্ধারণ করতে পারবেন না"। অন্যান্য সমস্ত প্রস্তাবনা আপনাকে সর্বোত্তম অনুমান করার উপায় দেয় (এবং গ্রন্থাগারগুলি)। কিন্তু শেষ পর্যন্ত তারা এখনও অনুমান।
মিহাই নীতা

9
Reader.getEncodingপাঠককে এনকোডিংটি ব্যবহারের জন্য সেট আপ করা হয়েছিল যা আপনার ক্ষেত্রে ডিফল্ট এনকোডিং।
করোল এস

উত্তর:


70

আমি জাভায় এনকোডিং সনাক্তকরণের জন্য jchardet এর অনুরূপ এই লাইব্রেরিটি ব্যবহার করেছি: http://code.google.com/p/ জুনভারসালচার্ডেট /


6
আমি দেখতে পেয়েছি যে এটি আরও নির্ভুল: jchardet.sourceforge.net (আমি আইএসও 8859-1, উইন্ডোজ -1222 , ইউএফ -8 এ এনকোডযুক্ত পশ্চিমাঞ্চলীয় ইউরোপীয় ভাষার নথিগুলির উপর পরীক্ষা করছিলাম)
জোয়েল

1
এই জুনিভারসালচারেট কাজ করে না। এটি ফাইলটি 100% উইন্ডোজ -1212 এনকোড থাকা সত্ত্বেও বেশিরভাগ সময় ইউটিএফ -8 সরবরাহ করে।
মস্তিষ্ক

1
জুনিভারসালচারেট এখন গিটহাবে
ডিমন

এটি পূর্ব ইউরোপীয় উইন্ডোজ
-1250

" Cl.cam.ac.uk/~mgk25/ucs/exferences/UTF-8-test.txt " থেকে ফাইলটিতে সনাক্ত করার জন্য আমি কোড স্নিপেট অনুসরণ করার চেষ্টা করেছি তবে সনাক্ত করা অক্ষর সেট হিসাবে বাতিল হয়ে গেছে। ইউনিভার্সালডেক্টর ud = নতুন ইউনিভার্সালডেক্টর (নাল); বাইট [] বাইটস = ফাইলআউটিলস.ড্রেডফিলিটোবাইটআরে (নতুন ফাইল (ফাইল)); ud.handleData (বাইটস, 0, বাইটস্ দৈর্ঘ্য); ud.dataEnd (); সনাক্ত করাচরসেট = ud.getDeteectedCharset ();
রোহিত ভার্মা

105

আপনি একটি সালিশী বাইট স্ট্রিমের এনকোডিং নির্ধারণ করতে পারবেন না। এটি এনকোডিংগুলির প্রকৃতি। একটি এনকোডিং মানে বাইট মান এবং এর উপস্থাপনের মধ্যে একটি ম্যাপিং। সুতরাং প্রতিটি এনকোডিং "সঠিক" হতে পারে।

GetEncoding () পদ্ধতি এনকোডিং যা (পড়া স্থাপন করা হয় ফিরে আসবে JavaDoc ) স্ট্রিম জন্য। এটি আপনার জন্য এনকোডিং অনুমান করবে না।

কিছু স্ট্রিম আপনাকে জানায় যে এগুলি তৈরি করতে কোন এনকোডিং ব্যবহৃত হয়েছিল: এক্সএমএল, এইচটিএমএল। তবে একটি নির্বিচারে বাইট স্ট্রিম নয়।

যাইহোক, আপনি নিজেই একটি এনকোডিং অনুমান করার চেষ্টা করতে পারেন। প্রতিটি ভাষার প্রতিটি চরের জন্য একটি সাধারণ ফ্রিকোয়েন্সি থাকে। ইংরেজিতে চর ই খুব প্রায়শই দেখা যায় তবে very খুব কমই উপস্থিত হবে। একটি আইএসও -8859-1 প্রবাহে সাধারণত 0x00 অক্ষর থাকে না। তবে একটি ইউটিএফ -16 স্ট্রিমের প্রচুর পরিমাণ রয়েছে।

অথবা: আপনি ব্যবহারকারীকে জিজ্ঞাসা করতে পারেন। আমি ইতিমধ্যে অ্যাপ্লিকেশনগুলি দেখেছি যা আপনাকে বিভিন্ন এনকোডিংগুলিতে ফাইলের একটি স্নিপেট উপস্থাপন করে এবং আপনাকে "সঠিক" নির্বাচন করতে বলছে।


18
এটি আসলে প্রশ্নের উত্তর দেয় না। অপ সম্ভবত ব্যবহার করা উচিত docs.codehaus.org/display/GUESSENC/Home বা icu-project.org/apiref/icu4j/com/ibm/icu/text/... বা jchardet.sourceforge.net
Christoffer Hammarström

23
তাহলে কীভাবে আমার সম্পাদক, নোটপ্যাড ++ ফাইলটি খুলবেন এবং আমাকে সঠিক অক্ষরগুলি দেখবেন?
মিমি

12
@ হামিদাম ভাগ্যক্রমে এটি আপনাকে সঠিক চরিত্রগুলি দেখায়। যখন এটি ভুলভাবে অনুমান করে (এবং এটি প্রায়শই ঘটে) তখন একটি বিকল্প রয়েছে (মেনু >> এনকোডিং) যা আপনাকে এনকোডিং পরিবর্তন করতে দেয়।
পেসারিয়ার

15
@ এডওয়ার্ড: "সুতরাং প্রতিটি এনকোডিং" "সঠিক হতে পারে।" একদম ঠিক না অনেকগুলি পাঠ্য এনকোডিংগুলিতে বেশ কয়েকটি নিদর্শন রয়েছে যা অবৈধ which এটি এমন পতাকা যা টেক্সটটি সম্ভবত এনকোডিং নয়। প্রকৃতপক্ষে, কোনও ফাইলের প্রথম দুটি বাইট দেওয়া, কেবলমাত্র 38% সংমিশ্রণই বৈধ UTF8 are প্রথম 5 কোডপয়েন্টের বৈধতা ইউটিএফ 8 যথাযথ হওয়ার সম্ভাবনাগুলি .77% এর চেয়ে কম। তেমনি, ইউটিএফ 16 বিই এবং এলই সাধারণত সহজেই প্রচুর সংখ্যক শূন্য বাইট দ্বারা চিহ্নিত করা হয় এবং তারা কোথায়।
হাঁসকে

38

এটা দেখ: http://site.icu-project.org/ (icu4j) তাদের কাছে আইওএসট্রিম থেকে চরসেট সনাক্ত করার জন্য লাইব্রেরি রয়েছে যা সহজ হতে পারে:

BufferedInputStream bis = new BufferedInputStream(input);
CharsetDetector cd = new CharsetDetector();
cd.setText(bis);
CharsetMatch cm = cd.detect();

if (cm != null) {
   reader = cm.getReader();
   charset = cm.getName();
}else {
   throw new UnsupportedCharsetException()
}

2
আমি চেষ্টা করেছিলাম কিন্তু এটি ব্যর্থ হয়েছে: আমি "öäüß" উভয়ই গ্রহনে 2 টি পাঠ্য ফাইল তৈরি করেছি। একটি সেট আইসো এনকোডিং এবং একটিতে utf8 - উভয়ই utf8 হিসাবে সনাক্ত করা হয়েছে! সুতরাং আমি আমার এইচডি (উইন্ডোজ) এর কোথাও নিরাপদ একটি ফাইল চেষ্টা করেছিলাম - এইটি সঠিকভাবে সনাক্ত করা হয়েছে ("উইন্ডোজ -১২২২")। তারপরে আমি এইচডি তে দুটি নতুন ফাইল তৈরি করেছি যার একটি সম্পাদকের সাথে সম্পাদিত হয়েছে অন্যটি নোটপ্যাড ++ সহ। উভয় ক্ষেত্রেই "বিগ 5" (চীনা) সনাক্ত হয়েছিল!
dermoritz

2
সম্পাদনা করুন: ঠিক আছে আমি সেমি.বেট কনফিডেন্স () - আমার সংক্ষিপ্ত "äöüß" আত্মবিশ্বাসের সাথে পরীক্ষা করা উচিত 10 সুতরাং আত্মবিশ্বাসটি ভাল ধারণা কী তা আমাকে সিদ্ধান্ত নিতে হবে - তবে এই প্রচেষ্টাটির (
চরসেট

1
নমুনা কোডের সরাসরি লিঙ্ক: userguide.icu-project.org/conversion/detection
james.garriss

27

এখানে আমার প্রিয়:

TikaEncodingDetector

নির্ভরতা:

<dependency>
  <groupId>org.apache.any23</groupId>
  <artifactId>apache-any23-encoding</artifactId>
  <version>1.1</version>
</dependency>

নমুনা:

public static Charset guessCharset(InputStream is) throws IOException {
  return Charset.forName(new TikaEncodingDetector().guessEncoding(is));    
}

GuessEncoding

নির্ভরতা:

<dependency>
  <groupId>org.codehaus.guessencoding</groupId>
  <artifactId>guessencoding</artifactId>
  <version>1.4</version>
  <type>jar</type>
</dependency>

নমুনা:

  public static Charset guessCharset2(File file) throws IOException {
    return CharsetToolkit.guessEncoding(file, 4096, StandardCharsets.UTF_8);
  }

2
নোট: টিকাএনকোডিং ডিটেক্টর 1.1 আসলে আইসিইউ 4 জে 3.4 CharsetDectector শ্রেণীর চারপাশে একটি পাতলা মোড়ক ।
স্টিফান

দুর্ভাগ্যক্রমে উভয় libs কাজ করে না। একটি ক্ষেত্রে এটি ইউএমএফ -8 ফাইলটি জার্মান উমলাউটের সাথে আইএসও -8859-1 এবং মার্কিন-এএসসিআইআই হিসাবে চিহ্নিত করে।
মস্তিষ্ক

1
@ ব্রেন: আপনার পরীক্ষিত ফাইলটি আসলে কোনও ইউটিএফ -8 ফর্ম্যাটে রয়েছে এবং এতে কি কোনও বিওএম অন্তর্ভুক্ত রয়েছে ( en.wikedia.org/wiki/Byte_order_mark )?
বেনি নিউজবাউয়ার

@ বেনিনিউজবাউয়ার ফাইলটি বিওএম ছাড়াই একটি ইউটিএফ -8। আমি এটিকে নোটপ্যাড ++ দিয়ে পরীক্ষা করেছিলাম, এছাড়াও এনকোডিং পরিবর্তন করে এবং "উমলাউট" এখনও দৃশ্যমান তা জোর দিয়ে।
মস্তিষ্ক

13

আপনি অবশ্যই একটি নির্দিষ্ট চরসেটের জন্য ফাইলটি একটি দিয়ে ডিকোড করে এবং "ত্রুটিযুক্ত-ইনপুট" বা "অক্ষম-অক্ষর" ত্রুটির জন্য পর্যালোচনা করে যাচাই করতে পারেন । অবশ্যই, এটি কেবল আপনাকে জানায় যদি একটি চরসেটটি ভুল হয়; এটি সঠিক কিনা তা আপনাকে জানায় না। তার জন্য, ডিকোডযুক্ত ফলাফলগুলি মূল্যায়নের জন্য আপনার তুলনা করার একটি ভিত্তি প্রয়োজন, উদাহরণস্বরূপ আপনি কি জানেন আগে থেকেই অক্ষরগুলি কিছু উপসেটে সীমাবদ্ধ থাকে, বা পাঠ্যটি কিছু কঠোর বিন্যাসে মেনে চলে কিনা? তল লাইনটি হল চার্সেট সনাক্তকরণ কোনও গ্যারান্টি ছাড়াই অনুমানের কাজ।CharsetDecoder


12

কোন লাইব্রেরি ব্যবহার করতে হবে?

এই লেখা হিসাবে, তারা তিনটি গ্রন্থাগার যে উত্থিত:

আমি অ্যাপাচি যেকোন 23 কে অন্তর্ভুক্ত করি না কারণ এটি হুডের নীচে আইসিইউ 4জ 3.4 ব্যবহার করে।

কোনটি সঠিক চরসেটটি সনাক্ত করেছে (বা যতটা সম্ভব কাছাকাছি)?

উপরের প্রতিটি লাইব্রেরির দ্বারা সনাক্ত করা চরসেটটি প্রমাণ করা অসম্ভব। তবে তাদের পরিবর্তে জিজ্ঞাসা করা এবং প্রত্যাবর্তিত প্রতিক্রিয়া স্কোর করা সম্ভব।

ফিরে আসা প্রতিক্রিয়া কীভাবে স্কোর করবেন?

প্রতিটি প্রতিক্রিয়া একটি পয়েন্ট বরাদ্দ করা যেতে পারে। একটি প্রতিক্রিয়া যত বেশি পয়েন্ট দেয়, সনাক্ত করা চারসেটের তত বেশি আস্থা থাকে। এটি একটি সাধারণ স্কোরিং পদ্ধতি। আপনি অন্যদের বিস্তারিত বলতে পারেন।

কোন নমুনা কোড আছে?

পূর্ববর্তী লাইনে বর্ণিত কৌশলটি বাস্তবায়নের জন্য এখানে একটি সম্পূর্ণ স্নিপেট।

public static String guessEncoding(InputStream input) throws IOException {
    // Load input data
    long count = 0;
    int n = 0, EOF = -1;
    byte[] buffer = new byte[4096];
    ByteArrayOutputStream output = new ByteArrayOutputStream();

    while ((EOF != (n = input.read(buffer))) && (count <= Integer.MAX_VALUE)) {
        output.write(buffer, 0, n);
        count += n;
    }
    
    if (count > Integer.MAX_VALUE) {
        throw new RuntimeException("Inputstream too large.");
    }

    byte[] data = output.toByteArray();

    // Detect encoding
    Map<String, int[]> encodingsScores = new HashMap<>();

    // * GuessEncoding
    updateEncodingsScores(encodingsScores, new CharsetToolkit(data).guessEncoding().displayName());

    // * ICU4j
    CharsetDetector charsetDetector = new CharsetDetector();
    charsetDetector.setText(data);
    charsetDetector.enableInputFilter(true);
    CharsetMatch cm = charsetDetector.detect();
    if (cm != null) {
        updateEncodingsScores(encodingsScores, cm.getName());
    }

    // * juniversalchardset
    UniversalDetector universalDetector = new UniversalDetector(null);
    universalDetector.handleData(data, 0, data.length);
    universalDetector.dataEnd();
    String encodingName = universalDetector.getDetectedCharset();
    if (encodingName != null) {
        updateEncodingsScores(encodingsScores, encodingName);
    }

    // Find winning encoding
    Map.Entry<String, int[]> maxEntry = null;
    for (Map.Entry<String, int[]> e : encodingsScores.entrySet()) {
        if (maxEntry == null || (e.getValue()[0] > maxEntry.getValue()[0])) {
            maxEntry = e;
        }
    }

    String winningEncoding = maxEntry.getKey();
    //dumpEncodingsScores(encodingsScores);
    return winningEncoding;
}

private static void updateEncodingsScores(Map<String, int[]> encodingsScores, String encoding) {
    String encodingName = encoding.toLowerCase();
    int[] encodingScore = encodingsScores.get(encodingName);

    if (encodingScore == null) {
        encodingsScores.put(encodingName, new int[] { 1 });
    } else {
        encodingScore[0]++;
    }
}    

private static void dumpEncodingsScores(Map<String, int[]> encodingsScores) {
    System.out.println(toString(encodingsScores));
}

private static String toString(Map<String, int[]> encodingsScores) {
    String GLUE = ", ";
    StringBuilder sb = new StringBuilder();

    for (Map.Entry<String, int[]> e : encodingsScores.entrySet()) {
        sb.append(e.getKey() + ":" + e.getValue()[0] + GLUE);
    }
    int len = sb.length();
    sb.delete(len - GLUE.length(), len);

    return "{ " + sb.toString() + " }";
}

উন্নতি:guessEncoding পদ্ধতি inputstream সম্পূর্ণরূপে পড়ে। বড় ইনপুটস্ট্রিমের জন্য এটি উদ্বেগের কারণ হতে পারে। এই সমস্ত লাইব্রেরি পুরো ইনপুটস্ট্রিমটি পড়বে। এটি চারসেট সনাক্তকরণের জন্য একটি বৃহত সময়ের খরচ বোঝায়।

প্রাথমিক ডেটা লোডিংকে কয়েকটি বাইটে সীমাবদ্ধ করা এবং কেবলমাত্র কয়েকটি বাইটে চরসেট সনাক্তকরণ করা সম্ভব।


8

উপরের লিবসগুলি সরল বিওএম ডিটেক্টর যা ফাইলের শুরুতে কোনও বিওএম থাকলে কেবল কোনটি অবশ্যই কাজ করে। কটাক্ষপাত http://jchardet.sourceforge.net/ অবলম্বন দিতে টেক্সট স্ক্যান


18
কেবলমাত্র ডগায়, তবে এই সাইটে কোনও "উপরে" নেই - আপনি যে লাইব্রেরিগুলিকে উল্লেখ করছেন তা উল্লেখ করে বিবেচনা করুন।
ম্যাকডোয়েল

6

যতদূর আমি জানি, সমস্ত প্রকার সমস্যার জন্য উপযুক্ত হওয়ার জন্য এই প্রসঙ্গে কোনও সাধারণ গ্রন্থাগার নেই। সুতরাং, প্রতিটি সমস্যার জন্য আপনার বিদ্যমান লাইব্রেরিগুলি পরীক্ষা করা উচিত এবং সেরাটি নির্বাচন করা উচিত যা আপনার সমস্যার সীমাবদ্ধতাগুলি পূরণ করে, তবে প্রায়শই সেগুলির কোনওটিই উপযুক্ত নয় is এই ক্ষেত্রে আপনি নিজের এনকোডিং ডিটেক্টর লিখতে পারেন! আমি যেমন লিখেছি ...

আমি অন্তর্নির্মিত উপাদান হিসাবে আইবিএম আইসিইউ 4 জ এবং মজিলা জেচারডেট ব্যবহার করে এইচটিএমএল ওয়েব পৃষ্ঠাগুলির চরসেট এনকোডিং সনাক্তকরণের জন্য একটি মেটা জাভা সরঞ্জাম লিখেছি। এখানে আপনি আমার সরঞ্জামটি সন্ধান করতে পারেন, দয়া করে অন্য কোনও কিছুর আগে README বিভাগটি পড়ুন। এছাড়াও, আপনি আমার কাগজে এবং এর উল্লেখগুলিতে এই সমস্যার কয়েকটি প্রাথমিক ধারণাটি পেতে পারেন ।

বেলো আমি কিছু সহায়ক মন্তব্য প্রদান করেছি যা আমি আমার কাজের অভিজ্ঞতা পেয়েছি:

  • চরসেট সনাক্তকরণ একটি নির্বোধ প্রক্রিয়া নয়, কারণ এটি মূলত পরিসংখ্যান সম্পর্কিত তথ্যের উপর ভিত্তি করে এবং যা ঘটেছিল তা সনাক্ত না করে অনুমান করা
  • আইবিএম-এর এই প্রসঙ্গে আইকিউ 4 জাই হ'ল প্রধান সরঞ্জাম im
  • টিকাএঙ্কোডিং ডিটেক্টর এবং লুসিন-আইসিইউ 4 জে উভয়ই আইসিইউ 4 জ ব্যবহার করছেন এবং তাদের যথার্থতার কোনও অর্থপূর্ণ পার্থক্য ছিল না যা থেকে আমার পরীক্ষাগুলিতে আইসিইউ 4 জ (বেশিরভাগ% 1, যেমনটি আমি মনে করি)
  • আইসিইউ ৪ জার্চেটের চেয়ে অনেক বেশি সাধারণ, আইসিইউ ৪ জে আইবিএম ফ্যামিলি এনকোডিংগুলিতে কিছুটা পক্ষপাতদুষ্ট এবং জ্যাচার্ডেট ইউটিএফ -৮-এর পক্ষে দৃ strongly়ভাবে পক্ষপাতদুষ্ট
  • এইচটিএমএল-ওয়ার্ল্ডে ইউটিএফ -8 এর ব্যাপক ব্যবহারের কারণে; সামগ্রিকভাবে আইসিইউ ৪ জের চেয়ে জ্যাচার্ডেট একটি ভাল পছন্দ, তবে এটি সেরা পছন্দ নয়!
  • ইসু-কেআর, ইইউসি-জেপি, SHIFT_JIS, বিআইজি 5 এবং জিবি ফ্যামিলি এনকোডিংগুলির মতো পূর্ব এশীয় নির্দিষ্ট এনকোডিংগুলির জন্য আইসিইউ 4j দুর্দান্ত for
  • আইসিইউ 4 জে এবং জ্যাচারেট উভয়ই উইন্ডোজ-1251 এবং উইন্ডোজ-1256 এনকোডিং সহ এইচটিএমএল পৃষ্ঠাগুলি নিয়ে কাজ করার ক্ষেত্রে পরাস্ত। সিরিজ-ভিত্তিক ভাষার জন্য রাশিয়ান এবং উইন্ডোজ -১66 ওরফে সিপি १२৫6 আরবিতে ব্যাপকভাবে ব্যবহৃত হয় উইন্ডোজ -১২১ ওরফে সিপি १२৫১ ব্যাপকভাবে ব্যবহৃত হয়
  • প্রায় সমস্ত এনকোডিং সনাক্তকরণ সরঞ্জাম পরিসংখ্যানমূলক পদ্ধতি ব্যবহার করছে, সুতরাং আউটপুট সঠিকতা ইনপুট এর আকার এবং বিষয়বস্তুর উপর দৃ of়ভাবে নির্ভর করে
  • কিছু এনকোডিংগুলি মূলত আংশিক পার্থক্যের সাথে একই হয়, তাই কিছু ক্ষেত্রে অনুমান করা বা সনাক্ত করা এনকোডিংটি ভুল হতে পারে তবে একই সাথে সত্য হতে পারে! উইন্ডোজ -1222 এবং আইএসও -8859-1 সম্পর্কে। (আমার কাগজের 5.2 বিভাগের অধীনে শেষ অনুচ্ছেদটি দেখুন)

5

আমি একটি দুর্দান্ত তৃতীয় পক্ষের লাইব্রেরি পেয়েছি যা প্রকৃত এনকোডিং সনাক্ত করতে পারে: http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding

আমি এটি ব্যাপকভাবে পরীক্ষা করিনি তবে এটি কাজ করে বলে মনে হচ্ছে।


"গুসেইনকোডিং" প্রকল্প ওয়েবসাইটের লিঙ্কটি
বেনি

5

আপনি যদি ICU4J ব্যবহার করেন ( http://icu-project.org/apiref/icu4j/ )

আমার কোডটি এখানে:

String charset = "ISO-8859-1"; //Default chartset, put whatever you want

byte[] fileContent = null;
FileInputStream fin = null;

//create FileInputStream object
fin = new FileInputStream(file.getPath());

/*
 * Create byte array large enough to hold the content of the file.
 * Use File.length to determine size of the file in bytes.
 */
fileContent = new byte[(int) file.length()];

/*
 * To read content of the file in byte array, use
 * int read(byte[] byteArray) method of java FileInputStream class.
 *
 */
fin.read(fileContent);

byte[] data =  fileContent;

CharsetDetector detector = new CharsetDetector();
detector.setText(data);

CharsetMatch cm = detector.detect();

if (cm != null) {
    int confidence = cm.getConfidence();
    System.out.println("Encoding: " + cm.getName() + " - Confidence: " + confidence + "%");
    //Here you have the encode name and the confidence
    //In my case if the confidence is > 50 I return the encode, else I return the default value
    if (confidence > 50) {
        charset = cm.getName();
    }
}

সমস্ত চেষ্টা করার প্রয়োজন মনে রাখবেন।

আমি আশা করি এটি আপনার পক্ষে কাজ করে।


আইএমও, এই উত্তরটি নিখুঁত। আপনি যদি আইসিইউ 4 জ ব্যবহার করতে চান তবে এর পরিবর্তে এটি ব্যবহার করে দেখুন: stackoverflow.com/a/4013565/363573
স্টিফান 1'15

4

আপনি যদি নিজের ডেটাটির এনকোডিং না জানেন তবে এটি নির্ধারণ করা এত সহজ নয় তবে আপনি এটি অনুমান করার জন্য কোনও লাইব্রেরি ব্যবহার করার চেষ্টা করতে পারেন । এছাড়াও, একটি অনুরূপ প্রশ্ন আছে


2

ISO8859_1 ফাইলগুলির জন্য এএসসিআইআই থেকে তাদের আলাদা করার সহজ উপায় নেই। ইউনিকোড ফাইলের ক্ষেত্রে তবে ফাইলের প্রথম কয়েকটি বাইটের ভিত্তিতে কেউ সাধারণত এটি সনাক্ত করতে পারে।

ইউটিএফ -8 এবং ইউটিএফ -16 ফাইলগুলি ফাইলের একেবারে শুরুতে একটি বাইট অর্ডার মার্ক (বিওএম) অন্তর্ভুক্ত করে। বিওএম হ'ল একটি শূন্য প্রস্থের নন-ব্রেকিং স্পেস।

দুর্ভাগ্যক্রমে, reasonsতিহাসিক কারণে, জাভা এটি স্বয়ংক্রিয়ভাবে সনাক্ত করে না। নোটপ্যাডের মতো প্রোগ্রামগুলি বিওএম চেক করবে এবং উপযুক্ত এনকোডিং ব্যবহার করবে। ইউনিক্স বা সাইগউইন ব্যবহার করে আপনি ফাইল কমান্ড দিয়ে বিওএম পরীক্ষা করতে পারেন। উদাহরণ স্বরূপ:

$ file sample2.sql 
sample2.sql: Unicode text, UTF-16, big-endian

জাভা জন্য, আমি আপনাকে এই কোডটি পরীক্ষা করে দেখার পরামর্শ দিচ্ছি যা সাধারণ ফাইল ফর্ম্যাটগুলি সনাক্ত করবে এবং সঠিক এনকোডিংটি নির্বাচন করবে: একটি ফাইল কীভাবে পড়বেন এবং সঠিকভাবে এনকোডিং নির্দিষ্ট করবেন


15
সমস্ত ইউটিএফ -8 বা ইউটিএফ -16 ফাইলের বিওএম নেই, এটির যেমন প্রয়োজন হয় না, এবং ইউটিএফ -8 বিওএম নিরুৎসাহিত হয়।
ক্রিস্টোফার হ্যামারস্ট্রিম

1

টিকাএনকোডিংডেক্টরটির বিকল্প হ'ল টিকা অটোডেক্টটরিডার ব্যবহার করা ।

Charset charset = new AutoDetectReader(new FileInputStream(file)).getCharset();

টিকে অটোডিটেক্টর রিডার সার্ভিস লোডার দিয়ে লোড এনকোডিংডেক্টর ব্যবহার করে। আপনি কোন এনকোডিং ডিটেক্টর বাস্তবায়ন ব্যবহার করেন?
স্টিফান

-1

সরল জাভাতে:

final String[] encodings = { "US-ASCII", "ISO-8859-1", "UTF-8", "UTF-16BE", "UTF-16LE", "UTF-16" };

List<String> lines;

for (String encoding : encodings) {
    try {
        lines = Files.readAllLines(path, Charset.forName(encoding));
        for (String line : lines) {
            // do something...
        }
        break;
    } catch (IOException ioe) {
        System.out.println(encoding + " failed, trying next.");
    }
}

এই পদ্ধতিটি এনকোডিংগুলি একে অপরের চেষ্টা করবে যতক্ষণ না কোনও কাজ হয় বা আমরা সেগুলি না শেষ করি। (বিটিডব্লিউ আমার এনকোডিং তালিকায় কেবলমাত্র সেই আইটেম রয়েছে কারণ এগুলি প্রতিটি জাভা প্ল্যাটফর্মে প্রয়োজনীয় চরসেট বাস্তবায়ন, https://docs.oracle.com/javase/9/docs/api/java/nio/charset/Charrset.html )


তবে আইএসও -8859-1 (আপনি তালিকাভুক্ত না করে এমন অনেকের মধ্যে) সর্বদা সফল হবে। এবং অবশ্যই এটি অনুমান করা যায় যা টেক্সট ফাইল যোগাযোগের জন্য প্রয়োজনীয় হারানো মেটাডেটা পুনরুদ্ধার করতে পারে না।
টম ব্লডজেট

হাই @ টমব্লডজেট, আপনি কি এনকোডিংয়ের ক্রমটি আলাদা হওয়া উচিত বলে পরামর্শ দিচ্ছেন?
আন্দ্রে

3
আমি বলছি যে অনেকে "কাজ করবে" তবে কেবল একটি "সঠিক"। এবং আপনাকে আইএসও -8859-1-র জন্য পরীক্ষা করার দরকার নেই কারণ এটি সর্বদা "কাজ" করবে।
টম ব্লডজেট

-12

আপনি কি কনস্ট্রাক্টরে উপযুক্ত চর সেট চয়ন করতে পারেন :

new InputStreamReader(new FileInputStream(in), "ISO8859_1");

8
এখানে মূল বক্তব্যটি ছিল চারসেটটি প্রোগ্রামক্রমে নির্ধারণ করা যায় কিনা to
জোয়েল

1
না, এটি আপনার পক্ষে অনুমান করবে না। আপনি এটি সরবরাহ করতে হবে।
কেভিন

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