কোটলিনে, আমি কীভাবে একটি স্ট্রিংয়ে ইনপুট স্ট্রিমের পুরো বিষয়বস্তু পড়ব?


105

আমি সম্প্রতি InputStreamকোটলিনের একটি স্ট্রিংয়ে একটি এর সম্পূর্ণ সামগ্রী পড়ার কোড দেখেছি , যেমন:

// input is of type InputStream
val baos = ByteArrayOutputStream()
input.use { it.copyTo(baos) }
val inputAsString = baos.toString()

এবং যদিও:

val reader = BufferedReader(InputStreamReader(input))
try {
    val results = StringBuilder()
    while (true) { 
        val line = reader.readLine()
        if (line == null) break
        results.append(line) 
    }
    val inputAsString = results.toString()
} finally {
    reader.close()
}

এমনকি এটি স্বচ্ছ দেখায় যেহেতু এটি স্বয়ংক্রিয়ভাবে বন্ধ হয় InputStream:

val inputString = BufferedReader(InputStreamReader(input)).useLines { lines ->
    val results = StringBuilder()
    lines.forEach { results.append(it) }
    results.toString()
}

বা এটির মধ্যে সামান্য প্রকরণ:

val results = StringBuilder()
BufferedReader(InputStreamReader(input)).forEachLine { results.append(it) }
val resultsAsString = results.toString()   

তারপরে এই কার্যকরী ভাঁজ জিনিস:

val inputString = input.bufferedReader().useLines { lines ->
    lines.fold(StringBuilder()) { buff, line -> buff.append(line) }.toString()
}

বা একটি খারাপ প্রকরণ যা বন্ধ করে না InputStream:

val inputString = BufferedReader(InputStreamReader(input))
        .lineSequence()
        .fold(StringBuilder()) { buff, line -> buff.append(line) }
        .toString()

তবে এগুলি সকলেই ছদ্মবেশী এবং আমি এর নতুন এবং বিভিন্ন সংস্করণগুলি সন্ধান করতে থাকি ... এবং তাদের মধ্যে কেউ কখনও এটিকে বন্ধও করে না InputStream। পড়ার একটি নন-ক্লঙ্কি (আইডোম্যাটিক) উপায় InputStreamকী?

দ্রষ্টব্য: এই প্রশ্নটি লেখক ইচ্ছাকৃতভাবে লিখেছেন এবং উত্তর দিয়েছেন ( স্ব-উত্তরযুক্ত প্রশ্ন ), যাতে সাধারণভাবে জিজ্ঞাসিত কোটলিন বিষয়গুলির বুদ্ধিমান উত্তরগুলি এসওতে উপস্থিত থাকে।

উত্তর:


216

কোটলিনের কেবলমাত্র এই উদ্দেশ্যে একটি নির্দিষ্ট এক্সটেনশন রয়েছে।

সহজতম:

val inputAsString = input.bufferedReader().use { it.readText() }  // defaults to UTF-8

এবং এই উদাহরণে আপনি সিদ্ধান্ত নিতে পারেন মধ্যে bufferedReader()বা ঠিক মধ্যে reader()। ফাংশনটিতে কলটি Closeable.use()ল্যাম্বদার মৃত্যুদন্ড কার্যকর হওয়ার পরে স্বয়ংক্রিয়ভাবে ইনপুটটি বন্ধ করে দেবে।

আরও পড়া:

আপনি যদি এই ধরণের জিনিস প্রচুর পরিমাণে করেন তবে আপনি এটি এক্সটেনশন ফাংশন হিসাবে লিখতে পারেন:

fun InputStream.readTextAndClose(charset: Charset = Charsets.UTF_8): String {
    return this.bufferedReader(charset).use { it.readText() }
}

যার পরে আপনি সহজে কল করতে পারেন:

val inputAsString = input.readTextAndClose()  // defaults to UTF-8

সাইড নোটে, সমস্ত কোটলিন এক্সটেনশন ফাংশনগুলির জন্য charsetইতিমধ্যে ডিফল্টটি জানা দরকার UTF-8, সুতরাং আপনার যদি অন্য কোনও এনকোডিং প্রয়োজন হয় তবে reader(charset)বা এর জন্য একটি এনকোডিং অন্তর্ভুক্ত করার জন্য আপনাকে উপরের কোডটি সামঞ্জস্য করতে হবে bufferedReader(charset)

সতর্কতা: আপনি সংক্ষিপ্ত উদাহরণগুলি দেখতে পাবেন:

val inputAsString = input.reader().readText() 

তবে এগুলি স্ট্রিমটি বন্ধ করে না । আপনি যে আইও ফাংশনটি ব্যবহার করছেন তা বন্ধ করে এবং কোনটি না তা নিশ্চিত করার জন্য আপনি যে সমস্ত আইও ফাংশন ব্যবহার করেন সেগুলির জন্য আপনি API ডকুমেন্টেশন চেক করেছেন তা নিশ্চিত করুন। সাধারণত যদি তারা শব্দটি অন্তর্ভুক্ত করে use(যেমন useLines()বা use()) আপনার পরে প্রবাহ বন্ধ করে দেয়। একটি ব্যতিক্রম হ'ল এটির File.readText()থেকে পৃথক Reader.readText()যে প্রাক্তন কোনও কিছুই খোলা রাখে না এবং দ্বিতীয়টির জন্য প্রকৃতপক্ষে একটি স্পষ্ট ঘনিষ্ঠতার প্রয়োজন হয়।

আরও দেখুন: কোটলিন আইও সম্পর্কিত এক্সটেনশন ফাংশন


1
আমি মনে করি আপনার প্রস্তাবিত এক্সটেনশন ফাংশনের জন্য "রিডটেক্সট" "ইউজেক্টেক্সট" এর চেয়ে আরও ভাল নাম হবে। যখন আমি "useText" পড়ার মত একটি ফাংশন আশা useবা useLinesযা কি "ব্যবহার" হচ্ছে তার উপর একটি ব্লক ফাংশন সঞ্চালন করে। যেমন inputStream.useText { text -> ... }অন্য দিকে, যখন আমি "readText" পড়ার আমি একটি ফাংশন যে পাঠ্য ফেরৎ আশা: val inputAsString = inputStream.readText()
mfulton26

সত্য, তবে রিডটেক্সট এর ইতিমধ্যে ভুল অর্থ রয়েছে, তাই এটি বোঝাতে চেয়েছিল এটি আরও useসেই ক্ষেত্রে কাজগুলির মতো । কমপক্ষে এই প্রশ্নোত্তর প্রসঙ্গে। হতে পারে একটি নতুন ক্রিয়া পাওয়া যেতে পারে ...
জয়সন মিনার্ড

3
@ এমফুল্টন26 আমি বন্ধ না readTextAndClose()হওয়ার readText()ধরণগুলির সাথে দ্বন্দ্ব এড়াতে এবং useল্যাম্বডা চেয়ে থাকা নিদর্শনগুলির সাথে এই উদাহরণটির জন্য গিয়েছিলাম , যেহেতু আমি নতুন স্টাডলিব ফাংশনটি প্রবর্তনের চেষ্টা করছি না আমি ব্যবহারের বিষয়ে কোনও বক্তব্য রাখার চেয়ে বেশি কিছু করতে চাই না ভবিষ্যতের শ্রম বাঁচাতে এক্সটেনশনগুলি।
জয়সন মিনার্ড

@ জেসনমিনার্ড আপনি কেন এটি উত্তরের জন্য চিহ্নিত করছেন না? এটি দুর্দান্ত যদিও :-)
পিয়োট্রেক 1543

2

একটি স্ট্রিং থেকে ইনপুট স্ট্রিমের সামগ্রীগুলি পড়ার একটি উদাহরণ

import java.io.File
import java.io.InputStream
import java.nio.charset.Charset

fun main(args: Array<String>) {
    val file = File("input"+File.separator+"contents.txt")
    var ins:InputStream = file.inputStream()
    var content = ins.readBytes().toString(Charset.defaultCharset())
    println(content)
}

রেফারেন্সের জন্য - কোটলিন পড়ুন ফাইল


আপনার উদাহরণে ত্রুটি রয়েছে: 1) ক্রস-প্ল্যাটফর্ম পাথের জন্য আপনার Paths.get()পদ্ধতিটি ব্যবহার করা উচিত । 2) স্ট্রিমগুলির জন্য - ট্রাই-রিসোর্স বৈশিষ্ট্য (কোটলিনে:। ব্যবহার {})
লেবেদেভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.