কোন লাইব্রেরি ব্যবহার করতে হবে?
এই লেখা হিসাবে, তারা তিনটি গ্রন্থাগার যে উত্থিত:
আমি অ্যাপাচি যেকোন 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 সম্পূর্ণরূপে পড়ে। বড় ইনপুটস্ট্রিমের জন্য এটি উদ্বেগের কারণ হতে পারে। এই সমস্ত লাইব্রেরি পুরো ইনপুটস্ট্রিমটি পড়বে। এটি চারসেট সনাক্তকরণের জন্য একটি বৃহত সময়ের খরচ বোঝায়।
প্রাথমিক ডেটা লোডিংকে কয়েকটি বাইটে সীমাবদ্ধ করা এবং কেবলমাত্র কয়েকটি বাইটে চরসেট সনাক্তকরণ করা সম্ভব।