আইউইটিস.ল্ট স্ট্রিংয়ের জন্য পেয়ারা সমতুল্য (ইনপুটস্ট্রিম)


106

স্ট্রিং-এ একটি পড়ার জন্য অ্যাপাচি কমন্স আইও-র একটি দুর্দান্ত সুবিধার পদ্ধতি রয়েছে IOUtils.toString ()InputStream

যেহেতু আমি অ্যাপাচি কমন্স এবং পেয়ারা থেকে সরে যাওয়ার চেষ্টা করছি : পেয়ারাতে কি এর সমতুল্য আছে? আমি com.google.common.ioপ্যাকেজে সমস্ত ক্লাসের দিকে তাকিয়েছিলাম এবং আমি এত সহজ কিছু পাইনি find

সম্পাদনা করুন: আমি চার্সেট সহ সমস্যাগুলি বুঝি এবং উপলব্ধি করি। এটি ঠিক তাই ঘটে যে আমি জানি যে আমার সমস্ত উত্সগুলি ASCII (হ্যাঁ, ASCII, এএনএসআই নয়) in, সুতরাং এই ক্ষেত্রে, এনকোডিং আমার পক্ষে কোনও সমস্যা নয়।


2
চরসেটগুলি সম্পর্কে: এটি একটি লাইব্রেরির জন্য নির্দিষ্ট করে বলা দরকার যে আপনি যা বোঝাচ্ছেন (উদাহরণস্বরূপ Charsets.US_ASCII) আপনি কী বলতে চান তা বোঝার চেয়ে আপনি "উহু, আমার অনুমান যাই হোক না কেন"? যা অনেককেই করতে খুশি মনে হয়। বিশেষত যেহেতু জাভা কোনও ইউটিএফ -8 এর মতো বোধগম্য কোনও ডিফল্ট ব্যবহার করে না।
কলিনড

আমি জানি. এজন্য আমি নিজের উত্তরে ইউটিএফ -8 ডিফল্ট সংস্করণ হিসাবে ব্যবহার করছি।
সান প্যাট্রিক ফ্লয়েড

আরও দেখুন ডক্স: code.google.com/p/guava-libraries/wiki/IOExplained
Vadzim

@ ভাদজিম যখন এই প্রশ্নটি জিজ্ঞাসা করা হয়েছিল তখন এই ডক্সটির অস্তিত্ব ছিল না :-)
সান প্যাট্রিক ফ্লয়েড

উত্তর:


85

কলমের উত্তরের বিষয়ে আপনি আপনার মন্তব্যে বলেছেন যে আপনি ব্যবহার করতে যাচ্ছেন

CharStreams.toString(new InputStreamReader(supplier.get(), Charsets.UTF_8))

এই কোডটি সমস্যাযুক্ত কারণ ওভারলোডের বিবরণ CharStreams.toString(Readable):

বন্ধ না করে Readable

এর অর্থ হ'ল আপনার InputStreamReaderএবং এক্সটেনশনের মাধ্যমে InputStreamফিরে supplier.get()আসা এই কোডটি সম্পূর্ণ হওয়ার পরে বন্ধ হবে না।

অন্যদিকে, আপনি যদি ইতিমধ্যে কোনও InputSupplier<InputStream>ওভারলোড ব্যবহার করে দেখে ফেলেছেন যে এই সুবিধাটি গ্রহণ করেন CharStreams.toString(InputSupplier<R extends Readable & Closeable>), toStringপদ্ধতিটি আপনার Readerজন্য তৈরি এবং বন্ধকরণ উভয়ই পরিচালনা করবে ।

এটি হ'ল জোন স্কিটের পরামর্শ, ঠিক তেমন কোনও ওভারলোড নেই যা ব্যতীত ইনপুট হিসাবে CharStreams.newReaderSupplierনেয় InputStream... আপনাকে এটি দিতে হবে InputSupplier:

InputSupplier<? extends InputStream> supplier = ...
InputSupplier<InputStreamReader> readerSupplier = 
    CharStreams.newReaderSupplier(supplier, Charsets.UTF_8);

// InputStream and Reader are both created and closed in this single call
String text = CharStreams.toString(readerSupplier);

মূল বিষয় InputSupplierহ'ল try-finallyসম্পদগুলি সঠিকভাবে বন্ধ হয়ে গেছে তা নিশ্চিত করার জন্য পেয়ারা সেই অংশগুলিকে পরিচালনা করার অনুমতি দেয় যাতে আপনার কুশল ব্লকের প্রয়োজন হয় handle

সম্পাদনা করুন: ব্যক্তিগতভাবে, আমি নিম্নলিখিতগুলি পেয়েছি (যা আমি এটি আসলে কীভাবে লিখতাম, কেবলমাত্র উপরের কোডের ধাপগুলি ভেঙে দিয়েছিলাম)

String text = CharStreams.toString(
    CharStreams.newReaderSupplier(supplier, Charsets.UTF_8));

হতে এ পর্যন্ত এই তুলনায় বাগাড়ম্বরপূর্ণ কম:

String text;
InputStreamReader reader = new InputStreamReader(supplier.get(), 
    Charsets.UTF_8);
boolean threw = true;
try {
  text = CharStreams.toString(reader);
  threw = false;
}
finally {
  Closeables.close(reader, threw);
}

এটি নিজেকে সঠিকভাবে পরিচালনা করার জন্য আপনাকে কম বেশি কী লিখতে হবে।


সম্পাদনা করুন: ফেব্রুয়ারী 2014

InputSupplierএবং OutputSupplierএবং যে পদ্ধতিগুলি সেগুলি ব্যবহার করে তা পেয়ারা ১.0.০ এ অবমুক্ত করা হয়েছে। তাদের প্রতিস্থাপন হয় ByteSource, CharSource, ByteSinkএবং CharSink। একটি দেওয়া ByteSource, আপনি এখন এর লিখিত সামগ্রী এর মতো পেতে Stringপারেন:

ByteSource source = ...
String text = source.asCharSource(Charsets.UTF_8).read();

দুর্দান্ত তথ্য (+1) জন্য ধন্যবাদ। তবে এটি খুব ভার্বোস। আমি মনে করি ক্লোজবেবলস.ক্লুয়েসুয়েটলি () এর সাথে গ্রহণযোগ্য উত্তর একত্রিত করা আরও সহজ।
সান প্যাট্রিক ফ্লয়েড

@ কলিনড: আমি আমার উত্তরের একটিতে আপনার পদ্ধতিটি ব্যবহার করেছি lease দয়া করে কোডটি দেখুন এবং আমাকে ইনপুটসপ্লিয়ার ব্যবহার করার সঠিক উপায় কিনা তা বলুন।
এমিল

1
@ কলিনডি, যদি ইনপুট স্ট্রিমটি কোনও ডওপোস্ট সার্লেটের অভ্যন্তর থেকে আসে তবে এটি বন্ধ করার কোনও মানে আছে কি? (বা এটি বন্ধ করার বিষয়ে উদ্বেগজনক)
ব্ল্যানকম্যান

CharStreams.toString (ইনপুটসপ্লেয়ার) এখন হ্রাস করা হয়েছে। আমি একটি চারসোর্স তৈরি করেছি (বাইটসোর্স থেকেCharSource হিসাবে ব্যবহার করে) তারপরে দস্তাবেজের পরামর্শ অনুসারে এর স্ট্রাস্টিং ব্যবহার করেছি।
জন লেহম্যান

4
@ TedM.Young: যদি সব আপনার আছে একটি হল InputStream, এবং আপনি যেমন পেতে চান String, CharStreams.toString(new InputStreamReader(inputStream, charset))যেতে উপায়। ByteSourceএবং CharSourceবিশেষত কেসগুলির ক্ষেত্রে যেখানে আপনার কাছে এমন কিছু আছে যা InputStreamএস বা Readerএর উত্স হিসাবে কাজ করতে পারে ।
কলিনড

56

যদি আপনার কাছে একটি থাকে তবে Readableআপনি ব্যবহার করতে পারেন CharStreams.toString(Readable)। সুতরাং আপনি সম্ভবত নিম্নলিখিতটি করতে পারেন:

String string = CharStreams.toString( new InputStreamReader( inputStream, "UTF-8" ) );

একটি চরিত্র সেট নির্দিষ্ট করতে আপনাকে বাধ্য করে, যা আমার ধারণা আপনার যাহাই হউক না কেন করা উচিত।


4
প্রকৃতপক্ষে, আমি আপনার এবং জন স্কিটির উত্তরগুলির সংমিশ্রণটি ব্যবহার করব: `চারস্ট্রিম.স স্ট্রিং (নতুন ইনপুট স্ট্রিম রিডার (সাপ্লায়ার.জেট (), চারসেটস.উইফএফ 8))`
সান প্যাট্রিক ফ্লয়েড

হ্যাঁ, বিকল্পগুলি একত্রিত করার প্রচুর উপায়!
কলম্ব

10
@ এসএসপি ফ্লয়েড: আপনার কাছে যদি InputSupplier<InputStream>আমি থাকে তবে আমি এর CharStreams.newReaderSupplier(supplier, Charsets.UTF_8)পরিবর্তে ব্যবহার করার পরামর্শ দিই new InputStreamReader। কারণ যে যখন দেওয়া হয় InputStreamReader, toStringহবে না যে ঘনিষ্ঠ Reader(এবং এইভাবে না অন্তর্নিহিত প্রবাহ!)। এর InputSupplierজন্য একটি ব্যবহার করে Reader, toStringপদ্ধতিটি আপনার Readerজন্য বন্ধটি পরিচালনা করবে ।
কলিনড

17

আপডেট : পিছনে তাকানো, আমি আমার পুরানো সমাধান পছন্দ করি না। এছাড়াও এটি এখন 2013 এবং জাভা 7 এর জন্য এখন আরও ভাল বিকল্প উপলব্ধ রয়েছে। এখন আমি এখন যা ব্যবহার করি তা এখানে:

InputStream fis = ...;
String text;
try (  InputStreamReader reader = new InputStreamReader(fis, Charsets.UTF_8)){
        text = CharStreams.toString(reader);
}

অথবা যদি ইনপুটসপ্লিয়ার সাথে থাকে

InputSupplier<InputStreamReader> spl = ...
try (  InputStreamReader reader = spl.getInput()){
        text = CharStreams.toString(reader);
    }

16

প্রায়। আপনি এই জাতীয় কিছু ব্যবহার করতে পারেন:

InputSupplier<InputStreamReader> readerSupplier = CharStreams.newReaderSupplier
    (streamSupplier, Charsets.UTF_8);
String text = CharStreams.toString(readerSupplier);

ব্যক্তিগতভাবে আমি এটি "দুর্দান্ত" বলে মনে করি নাIOUtils.toString(InputStream) - কারণ এটি প্ল্যাটফর্মের সর্বদা ডিফল্ট এনকোডিং ব্যবহার করে, যা আপনি যা চান তা প্রায় কখনও হয় না। একটি ওভারলোড রয়েছে যা এনকোডিংয়ের নাম নেয় তবে নাম ব্যবহার করা কোনও দুর্দান্ত ধারণা আইএমও নয়। এজন্যই আমি পছন্দ করি Charsets.*

সম্পাদনা: উপরের InputSupplier<InputStream>হিসাবে একটি হিসাবে প্রয়োজন হয় না streamSupplier। আপনি যদি ইতিমধ্যে স্ট্রিমটি পেয়ে থাকেন তবে আপনি সহজেই এটিকে কার্যকর করতে পারবেন যদিও:

InputSupplier<InputStream> supplier = new InputSupplier<InputStream>() {
    @Override public InputStream getInput() {
        return stream;
    }
};

জোন, রিকোয়েস্ট.ইটপুট স্ট্রিমের মাধ্যমে স্ট্রিম? এছাড়াও, আপনার @ কলামের উত্তরে উল্লিখিত কলিনডের মতো প্রবাহ বন্ধ হবে?
ব্ল্যাঙ্কম্যান

ওহ, এবং এটি একটি সার্লেট ডপপোস্ট পরিবেশ, আমি কি কোনওভাবে স্ট্রিমটি বন্ধ করব?
ফাঁকা

@ ব্লাঙ্কম্যান: আহ, সুতরাং এটি আপনার প্রসঙ্গ - এটি আপনার প্রশ্ন থেকে মোটেও পরিষ্কার ছিল না। আপনি কোনও অনুরোধের স্ট্রিমটি বন্ধ করেন কিনা তা খুব বেশি কিছু যায় আসে না, তবে আমি সাধারণত এটি করতাম। যদিও আমি এই উত্তরটি সম্পাদনা করব - এমন কোনও ওভারলোড নেই seems
জন স্কিটি

1
আমি এখনই এটি করছি: স্ট্রিং পেইলড = চারস্ট্রিমস.টোস্ট্রিং (নতুন ইনপুটস্ট্রিমআরডার (অনুরোধ.জিটইনপুটস্ট্রিম (), "ইউটিএফ -8"));
ফাঁকা

1
@ বিওনরোপ: আমার ধারণা একটি মধ্যবর্তী পদ্ধতির মধ্যে রয়েছে Charsets.UTF_8.name()- আরও টাইপো-প্রতিরোধী।
জন স্কিটি

11

আর একটি বিকল্প হ'ল স্ট্রিম থেকে বাইটগুলি পড়ুন এবং সেগুলি থেকে একটি স্ট্রিং তৈরি করুন:

new String(ByteStreams.toByteArray(inputStream))
new String(ByteStreams.toByteArray(inputStream), Charsets.UTF_8)

এটি 'খাঁটি' পেয়ারা নয়, এটি খানিকটা খাটো।


দুর্ভাগ্যক্রমে, ByteStreams.toByteArray()জাভাডোক অনুসারে, স্ট্রিমটি বন্ধ করে না।
অ্যালকেমিস্ট

সেটা সত্য. প্রবাহ বন্ধ করে এমন কোনও পেয়ারা ফাংশন আমি দেখিনি। ভাল, কাছের কিউটলি বাদে।
ponomandr

1
সাধারণত, স্ট্রিমটি চেষ্টা-সহ-সংস্থাগুলির বিবৃতিতে খোলা হয় এবং স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায়, তাই এটি বাইটআর্রির ()
পোনোমন্ডর

4

গৃহীত উত্তরের উপর ভিত্তি করে, এখানে একটি ইউটিলিটি পদ্ধতি রয়েছে যা IOUtils.toString()(এবং পাশাপাশি একটি চরসেট সহ একটি ওভারলোডেড সংস্করণ) এর আচরণকে ঠাট্টা করে । এই সংস্করণটি নিরাপদ হওয়া উচিত, তাই না?

public static String toString(final InputStream is) throws IOException{
    return toString(is, Charsets.UTF_8);
}


public static String toString(final InputStream is, final Charset cs)
throws IOException{
    Closeable closeMe = is;
    try{
        final InputStreamReader isr = new InputStreamReader(is, cs);
        closeMe = isr;
        return CharStreams.toString(isr);
    } finally{
        Closeables.closeQuietly(closeMe);
    }
}

আমার কাছে বেশ সুন্দর লাগছে। আপনি যদি 1 টি শট স্ট্রিম এবং পাঠকদের পরিবর্তে পুনরায় ব্যবহারযোগ্য ইনপুট সরবরাহকারীদের বিবেচনা করতে শিখেন তবে পেয়ারাটির আইও স্টাফ সবচেয়ে ভাল কাজ করে তবে আপনি অনুমান করি যেহেতু আপনি বিদ্যমান আইইউটিস কোডটি রূপান্তর করছেন যা একটি বড় পরিবর্তন হবে a
কলিনড

2
আমার পেয়ারা 14 এ, ঘনিষ্ঠভাবে ইতিমধ্যে অবমুক্ত করা হয়েছে। পরামর্শ চেষ্টা-সঙ্গে-সম্পদ ব্যবহার বৈশিষ্ট্য যে জাভা 7. এই বিষয়ে আরও বিদ্যমান হয় code.google.com/p/guava-libraries/wiki/...
Bertie

2
@ অ্যালবার্টকাম সম্মত হয়েছেন। তবে মনে রাখবেন: এই উত্তরটি তিন বছরের পুরানো।
সান প্যাট্রিক ফ্লয়েড

@ সানপ্যাট্রিকফ্লাইড: ধন্যবাদ! আসলে আমি আপনার উত্তর থেকে শুরু করে নতুন সমাধান পেয়েছি। আমি অন্যদের জন্য মন্তব্য যুক্ত করার কথা ভাবছিলাম যারা সম্ভবত নতুন সংস্করণটি ব্যবহার করছেন। :)
বার্তি

4

ক্লাসপথ সংস্থান থেকে ইনপুট স্ট্রিমটি আসার ক্ষেত্রে অনেক ছোট অটোক্লোজিং সমাধান রয়েছে:

URL resource = classLoader.getResource(path);
byte[] bytes = Resources.toByteArray(resource);
String text = Resources.toString(resource, StandardCharsets.UTF_8);

আইওএক্সপ্লাইনেড দ্বারা অনুপ্রাণিত হয়ে পেয়ারা রিসোর্স ব্যবহার করুন ।


1
এই প্রশ্নটি যখন জিজ্ঞাসা করা হয়েছিল তখন সম্পদ শ্রেণীর অস্তিত্ব ছিল না, তবে আপনি ঠিক বলেছেন: আজ সম্ভবত সেই পথটিই হবে। ধন্যবাদ
সান প্যাট্রিক ফ্লয়েড

2

সম্পাদনা (2015): আমি জানি জাভা / অ্যান্ড্রয়েডে I / O এর জন্য Okio হ'ল সেরা বিমূর্ততা এবং সরঞ্জাম। আমি সব সময় এটি ব্যবহার।

এফডব্লিউআইডাব্লু আমি এখানে যা ব্যবহার করি তা এখানে।

যদি আমার হাতে ইতিমধ্যে একটি স্ট্রিম থাকে, তবে:

final InputStream stream; // this is received from somewhere
String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() {
    public InputStream getInput() throws IOException {
        return stream;
    }
}, Charsets.UTF_8));

আমি যদি একটি স্ট্রিম তৈরি করছি:

String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() {
    public InputStream getInput() throws IOException {
        return <expression creating the stream>;
    }
}, Charsets.UTF_8));

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

final Context context = ...;
String s = CharStreams.toString(CharStreams.newReaderSupplier(new InputSupplier<InputStream>() {
    public InputStream getInput() throws IOException {
        return context.getAssets().open("my_asset.txt");
    }
}, Charsets.UTF_8));

সব এখনই হ্রাস করা হয়েছে। :(
ব্যবহারকারী 3562927

1
ব্যবহার করে দেখুন github.com/square/okio পরিবর্তে - আমি কিছুদিনের এখন পেয়ারা এর ইনপুট / আউটপুট ব্যবহার করেন নি, Okio কেবল ভাল হয়
orip

0

একটি দৃ concrete় উদাহরণের জন্য, আমি এখানে একটি Android পাঠ্য ফাইল সম্পদটি কীভাবে পড়তে পারি তা এখানে:

public static String getAssetContent(Context context, String file) {
    InputStreamReader reader = null;
    InputStream stream = null;
    String output = "";

    try {
        stream = context.getAssets().open(file);
        reader = new InputStreamReader(stream, Charsets.UTF_8);
        output = CharStreams.toString(reader);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

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