জাভা ফাইলরেডার এনকোডিংয়ের সমস্যা


130

আমি কিছু পাঠ্য ফাইল পড়তে এবং সেগুলিকে একটি স্ট্রিংয়ে রূপান্তর করতে java.io.FileReader ব্যবহার করার চেষ্টা করেছি, তবে আমি দেখতে পেয়েছি ফলাফলটি ভুলভাবে এনকোড হয়েছে এবং মোটেও পঠনযোগ্য নয়।

আমার পরিবেশটি এখানে:

  • উইন্ডোজ 2003, ওএস এনকোডিং: সিপি 1252

  • জাভা 5.0

আমার ফাইলগুলি ইউটিএফ -8 এনকোডযুক্ত বা সিপি 1252 এনকোডযুক্ত রয়েছে এবং তাদের মধ্যে কিছুতে (ইউটিএফ -8 এনকোডযুক্ত ফাইলগুলি) চাইনিজ (ল্যাটিনবিহীন) অক্ষর থাকতে পারে।

আমি আমার কাজটি করতে নিম্নলিখিত কোডগুলি ব্যবহার করি:

   private static String readFileAsString(String filePath)
    throws java.io.IOException{
        StringBuffer fileData = new StringBuffer(1000);
        FileReader reader = new FileReader(filePath);
        //System.out.println(reader.getEncoding());
        BufferedReader reader = new BufferedReader(reader);
        char[] buf = new char[1024];
        int numRead=0;
        while((numRead=reader.read(buf)) != -1){
            String readData = String.valueOf(buf, 0, numRead);
            fileData.append(readData);
            buf = new char[1024];
        }
        reader.close();
        return fileData.toString();
    }

উপরের কোডটি কাজ করে না। আমি খুঁজে পেয়েছি যে ফাইলআরডারটির এনকোডিংটি CP1252, এমনকি যদি পাঠ্যটি ইউটিএফ -8 এনকোডড থাকে। তবে java.io.FileReader এর জাভাডোক বলেছেন যে:

এই শ্রেণীর নির্মাতারা ধরে নেন যে ডিফল্ট অক্ষর এনকোডিং এবং ডিফল্ট বাইট-বাফার আকার উপযুক্ত।

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


আপনারও স্ট্রিং.ভালিউওফ () লুপের ভিতরে আলগা করে স্ট্রিংবফার.অ্যাপেন্ড (চর [], ইনট, ইনট) সরাসরি ব্যবহার করা উচিত। এটি চরের অনুলিপি অনেকটা সংরক্ষণ করে []। স্ট্রিংবুফারকে স্ট্রিংবুফারের সাথে প্রতিস্থাপন করুন। যদিও এর কোনওটিই আপনার প্রশ্ন সম্পর্কে নয়, যদিও '।
জোছিম সৌর

1
আমি এটি বলতে ঘৃণা করি, তবে আপনি যে অংশটি আটকে দিয়েছেন তার ঠিক পরে আপনি জাভাক ডকটি পড়েছেন? আপনি জানেন, যে অংশটি বলছে "এই মানগুলি নিজেই নির্দিষ্ট করতে একটি ফাইলপুট স্ট্রিমে একটি ইনপুট স্ট্রিম রিডার তৈরি করুন?"
পাওয়ারলর্ড

আপনার মন্তব্যের জন্য ধন্যবাদ, আসলে আমি জাভাডকটি পড়েছি, তবে যা নিশ্চিত তা নয় যে আমি নিজেই এই মানগুলি নির্দিষ্ট করেছিলাম কিনা এবং "ফাইলপুট স্ট্রিমে একটি ইনপুটস্ট্রিমার্ডার নির্মাণ করুন" এ স্যুইচ করুন।
nybon 1

হ্যাঁ, আপনি যদি জানেন যে ফাইলটি প্ল্যাটফর্মের ডিফল্ট এনকোডিং ব্যতীত অন্য কোনও কিছুতে রয়েছে তবে আপনাকে ইনপুটস্ট্রিমআরইডারটি বলতে হবে কোনটি ব্যবহার করা উচিত।
অ্যালান মুর

উত্তর:


248

হ্যাঁ, আপনি যে ফাইলটি পড়তে চান তার এনকোডিং নির্দিষ্ট করতে হবে

হ্যাঁ, এর অর্থ হ'ল যে ফাইলটি আপনি পড়তে চান তার এনকোডিংটি আপনাকে জানতে হবে।

না, প্রদত্ত কোনও "সরল পাঠ্য" ফাইলের এনকোডিং অনুমান করার কোনও সাধারণ উপায় নেই ।

ওয়ান-আর্গুমেন্ট নির্মাণকারীরাFileReader সর্বদা প্ল্যাটফর্ম ডিফল্ট এনকোডিং ব্যবহার করে যা সাধারণত খারাপ ধারণা

যেহেতু জাভা 11 FileReaderএমন কনস্ট্রাক্টরও অর্জন করেছে যা একটি এনকোডিং গ্রহণ করে: new FileReader(file, charset)এবং new FileReader(fileName, charset)

জাভা এর পূর্ববর্তী সংস্করণগুলিতে আপনাকে ব্যবহার করা দরকার ।new InputStreamReader(new FileInputStream(pathToFile), <encoding>)


1
ইনপুট স্ট্রিম = নতুন ফাইলআইপুট স্ট্রিম (ফাইলের নাম); এখানে আমি রাশিয়ান ফাইলের নামের সাথে ত্রুটি খুঁজে পাইনি
ভানু শর্মা

3
ইনপুট স্ট্রিমরিডার ব্যবহারের পরামর্শের জন্য +1, তবে কোড ব্লকগুলিতে লিঙ্কগুলি ব্যবহার করে কোডটি অনুলিপি করা এবং পেস্ট করা শক্ত হয়ে যায়, যদি এটি পরিবর্তন করা যায় তবে thx
ফেরিবিগ

1
এটি কী এনকোডিংগুলিতে "ইউটিএফ -8" বা "ইউটিএফ 8" হবে? এনকোডিং সম্পর্কিত জাভা এসই রেফারেন্স অনুসারে , যেহেতু InputStreamReaderএকটি java.ioশ্রেণি, তাই এটি "ইউটিএফ 8" হবে?
নোবেলপ্লিফ্ট

9
@ নোবেলপ্লিট: নিরাপদ বাজিটি হ'ল StandardCharsets.UTF_8, সেখানে ভুল টাইপ করার কোনও সম্ভাবনা নেই ;-) তবে হ্যাঁ, আপনি যদি স্ট্রিং দিয়ে যান "UTF8"তবে এটি সঠিক হবে (যদিও আমি মনে করি এটি উভয়ভাবেই গ্রহণ করবে)।
জোছিম সউর

1
@ জোয়াচিমসৌর আসলে, এটি Byte Order Mark.. এর পাশাপাশি বায়ার অর্ডার প্রতিষ্ঠার অন্যতম উদ্দেশ্য! :) এরকম আমি অদ্ভুত দেখতে পাই যে জাভার ফাইলআরডার এমন ইউটিএফ -16 স্বয়ংক্রিয়ভাবে সনাক্ত করতে সক্ষম নয় যা এরকম একটি বিওএম আছে ... আসলে আমি একবার এটি লিখেছিলাম UnicodeFileReaderযা এটি ঠিক করে দেয়। দুর্ভাগ্যক্রমে বন্ধ উত্স, তবে গুগলের কাছে এটি ইউনিকোডেরীডার রয়েছে যা খুব অনুরূপ।
স্টিজন ডি উইট

79

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

যদি এই "সেরা অনুমান "টি সঠিক না হয় তবে আপনাকে অবশ্যই এনকোডিং স্পষ্টভাবে নির্দিষ্ট করতে হবে। দুর্ভাগ্যক্রমে, FileReaderএটি (এপিআইতে প্রধান তদারকি) অনুমতি দেয় না। পরিবর্তে, আপনাকে ব্যবহার করতে হবে new InputStreamReader(new FileInputStream(filePath), encoding)এবং আদর্শভাবে ফাইলটি সম্পর্কে মেটাডেটা থেকে এনকোডিং নিতে হবে।


24
"এপিআইতে প্রধান তদারকি" - এই ব্যাখ্যার জন্য ধন্যবাদ - আমি ভাবছিলাম যে কেন আমি পরে যে নির্মাতাকে খুঁজে পেলাম না!
চিয়ারস

@ ভানু শর্মা: এটি একটি ভিন্ন স্তরের একটি এনকোডিংয়ের সমস্যা, আপনি ফাইলের নামটি কোথা থেকে পাচ্ছেন তা পরীক্ষা করে দেখুন এবং সংকলকটি কীভাবে এনকোডিং ব্যবহার করছে তা যদি হার্ডকোডযুক্ত হয়।
মাইকেল বর্গওয়ার্ট

1
@ ভানুশর্মা: ফাইলনাম এনকোডিং ইস্যুগুলির এই প্রশ্নটির সাথে কিছুই করার নেই। প্রচুর বিদ্যমান "কেন জাভায় ইউনিকোড ফাইলের নাম কাজ করে না" প্রশ্নগুলির মধ্যে একটি দেখুন। স্পোলার: jaa.io এপিআই এর মত ফাইলরেডার সি স্ট্যান্ডার্ড লাইব্রেরি ফাইল সিস্টেম কলগুলি ব্যবহার করে, যা উইন্ডোজে ইউনিকোড সমর্থন করতে পারে না; পরিবর্তে java.nio ব্যবহার বিবেচনা করুন।
বোবিন্স

1
" FileReaderজাভার প্ল্যাটফর্মের ডিফল্ট এনকোডিং ব্যবহার করে, এটি যে কম্পিউটারটি চলছে তার সিস্টেম সেটিংসের উপর নির্ভর করে এবং সেই লোকেলের ব্যবহারকারীদের মধ্যে সাধারণত সর্বাধিক জনপ্রিয় এনকোডিং।" আমি এটা বলব না। কমপক্ষে উইন্ডোজ। কিছু অদ্ভুত প্রযুক্তিগত / historicalতিহাসিক কারণে, জেভিএম এই বিষয়টিকে উপেক্ষা করে যে 'সমস্ত নতুন অ্যাপ্লিকেশন'-এর জন্য উইন্ডোজে ইউনিকোড প্রস্তাবিত এনকোডিং এবং এর পরিবর্তে সর্বদা লেগ্যাসি অ্যাপ্লিকেশনগুলির ফ্যালব্যাক হিসাবে কনফিগার করা লিগ্যাসি এনকোডিংটিই ' প্ল্যাটফর্ম ডিফল্ট 'বলে কাজ করে।
স্টিজন ডি উইট

6
আমি এমনকি এতদূর বলব যে আপনার জাভা অ্যাপ্লিকেশনটি প্রতিবার ফাইল / স্ট্রিম / সংস্থানগুলি পড়তে বা লেখার সময় এনকোডিংগুলিকে স্পষ্টভাবে উল্লেখ না করে, এটি ভেঙে গেছে , কারণ এটি কখনই নির্ভরযোগ্যভাবে কাজ করতে পারে না
স্টিজন ডি উইট


6

জাভা 7+ ডকের জন্য আপনি এটি ব্যবহার করতে পারেন:

BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);

এখানে সমস্ত চরসেট ডক রয়েছে

উদাহরণস্বরূপ আপনার ফাইলটি সিপি 1252 এ থাকলে এই পদ্ধতিটি ব্যবহার করুন

Charset.forName("windows-1252");

আইও এবং এনআইও উভয় দস্তাবেজের জন্য জাভা এনকোডিংয়ের জন্য অন্যান্য প্রচলিত নাম এখানে রয়েছে

আপনি ঠিক এনকোডিং আপনি একটি ফাইল পেয়েছিলাম সাথে জানা না থাকলে, আপনি Google থেকে এই টুল মত কিছু তৃতীয় পক্ষের লিব ব্যবহার করতে পারেন এই যা মোটামুটি ঝরঝরে কাজ করে।


1

ইনপুট স্ট্রিম রিডার সহ ফাইলইনপুট স্ট্রিম সরাসরি ফাইলরেডার ব্যবহার করার চেয়ে ভাল, কারণ পরেরটি আপনাকে এনকোডিং চরসেট নির্দিষ্ট করার অনুমতি দেয় না।

এখানে বাফার্ডারীডার, ফাইলআইপুটপ্রবাহ এবং ইনপুটস্ট্রিম রিডার একসাথে ব্যবহার করার উদাহরণ রয়েছে যাতে আপনি কোনও ফাইলের লাইন পড়তে পারেন।

List<String> words = new ArrayList<>();
List<String> meanings = new ArrayList<>();
public void readAll( ) throws IOException{
    String fileName = "College_Grade4.txt";
    String charset = "UTF-8";
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(
            new FileInputStream(fileName), charset)); 

    String line; 
    while ((line = reader.readLine()) != null) { 
        line = line.trim();
        if( line.length() == 0 ) continue;
        int idx = line.indexOf("\t");
        words.add( line.substring(0, idx ));
        meanings.add( line.substring(idx+1));
    } 
    reader.close();
}

0

অন্যটির জন্য লাতিন ভাষার উদাহরণ হিসাবে সিরিলিক আপনি এরকম কিছু ব্যবহার করতে পারেন:

FileReader fr = new FileReader("src/text.txt", StandardCharsets.UTF_8);

এবং নিশ্চিত হয়ে নিন যে আপনার .txtফাইলটি সংরক্ষণ করা হয়েছে UTF-8(তবে ডিফল্ট হিসাবে নয় ANSI) ফর্ম্যাট। চিয়ার্স!

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