ইনপুট স্ট্রিমটিকে স্কালায় একটি স্ট্রিতে রূপান্তর করার আইডোমেটিক উপায়


111

আমার একটি সহজ ফাংশন রয়েছে যা আমি জাভাতে ইনপুট স্ট্রিমটিকে স্ট্রিংয়ে রূপান্তর করার জন্য ব্যবহার করেছি। স্ক্যালায় সরাসরি অনুবাদ এটি:

  def inputStreamToString(is: InputStream) = {
    val rd: BufferedReader = new BufferedReader(new InputStreamReader(is, "UTF-8")) 
    val builder = new StringBuilder()    
    try {
      var line = rd.readLine 
      while (line != null) { 
        builder.append(line + "\n")
        line = rd.readLine
      }
    } finally {
      rd.close
    }
    builder.toString
  }

স্ক্যালায় এটি করার কোনও মূ ?় উপায় আছে?

উত্তর:


197

স্কেল> = 2.11 এর জন্য

scala.io.Source.fromInputStream(is).mkString

স্কেলার জন্য <2.11:

scala.io.Source.fromInputStream(is).getLines().mkString("\n")

প্রায় একই জিনিস করে। আপনি লাইন পেতে এবং তারপরে সেগুলি আবার একসাথে করতে চান তা নিশ্চিত নয়। আপনি যদি স্ট্রিমের অবরুদ্ধকরন ধরে নিতে পারেন তবে আপনি কেবল ব্যবহার করতে পারেন .available, পুরো জিনিসটি বাইট অ্যারেতে পড়তে পারেন এবং সরাসরি এটি থেকে স্ট্রিং তৈরি করতে পারেন।


2
একটি সম্ভাব্য কারণ, যা আমি নিজেকে ব্যবহার করেছি, তা হ'ল বিভিন্ন অপারেটিং সিস্টেমে লাইন এন্ডেজগুলি স্বাভাবিক করা।
কেভিন রাইট

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

সমাধানটি খুব নিরাপদ নয় কারণ এটি গেটলাইনস () ব্যবহার করে; ইনপুট স্ট্রিমের কোনও "নতুন লাইন" অক্ষর না থাকলে কী হবে? তারপরে পুরো বিষয়টিকে
অবরুদ্ধ করে

বেশ খারাপ সমাধান। যদি ইনপুটস্ট্রিমে ডস লাইন-এন্ডিংস থাকে (\ r \ n)। এগুলি এই পদ্ধতি দ্বারা সরানো হবে। এছাড়াও, যদিও এমকেস্ট্রিং একটি বাফার ব্যবহার করে তবে অবশ্যই অক্ষরগুলির ব্লকগুলি পড়ার পক্ষে এটি দ্রুততর হবে।
ডিবিবেকে

1
@ রেক্সকের আপনি কি দয়া করে আপনার উত্তরে উল্লিখিত "পারফরম্যান্স বাগ" উল্লেখ করতে পারেন? আমি কয়েকটি বেসিক টেস্টকেসগুলি সহ উভয় সংস্করণ পরীক্ষা করেছি এবং কোনও সমস্যায় পড়িনি।
সাহিল স্যারীন

74

Source.fromInputStream(is).mkString("") কাজও করবে .....


ভাল যুক্তি; উত্স প্রসারিত এমন কিছু তৈরি করে Iterator[Char]
রেক্স কের 16

8
সাধারণত এই ধরণের জিনিসটি করার সময় অক্ষর এনকোডিং নির্দিষ্ট করা ভাল অভ্যাস। সেই লক্ষ্যে: Source.fromInputStream(is)(Codec.UTF8).mkString
কনার ডয়েল

এটি সংক্ষিপ্ত, তবে এটি স্ট্রিমটি বন্ধ করে না, যেখানে মূল জাভা কোডটি করেছে।
ধনী

@ রিচ, fromInputStream()কমপক্ষে স্কেলা ২.১১ এ স্ট্রিমটি বন্ধ করে দেখা যাচ্ছে।
jaco0646

2
@ jaco0646 - এটি স্ট্রিমটি বন্ধ করে না। আমি সবেমাত্র পরীক্ষা করেছি। এখানে এটি প্রমাণিত ডেমো কোড রয়েছে: gist.github.com/RichardBradley/bcd1a5e61fcc83e4e59f8b9b0bc2301c
সমৃদ্ধ

13

এটি করার দ্রুত উপায়:

    private def inputStreamToString(is: InputStream) = {
        val inputStreamReader = new InputStreamReader(is)
        val bufferedReader = new BufferedReader(inputStreamReader)
        Iterator continually bufferedReader.readLine takeWhile (_ != null) mkString
    }

"দ্রুত"? তবে এটি আমাকে কীভাবে করতে হবে তার উত্তর সরবরাহ করেছে যখন আমার কাছে কেবল একটি Readerএবং একটি নেই InputStream
বীপডোগ

3
কেবল প্রথম লাইন এড়িয়ে যান এবং inputStreamReaderপদ্ধতিতে পাস করুন।
কামিল লেলোনেক

1
এটি স্কেলাল.আই.এস.এস.এস.এস. সোর্স থেকে ২.১১..7 এর চেয়ে দ্রুততর আকারের ক্রম। আমি এটির একটি মূল বেনমার্ক লিখেছিলাম এবং বেশিরভাগ সময়, এটি বড় ফাইলগুলির জন্য প্রায় 5% দ্রুত ছিল (পরীক্ষাটি ছিল 35 এমবি পাঠ্য ফাইল) ছোট ফাইলগুলির জন্য 2,800% পর্যন্ত দ্রুত (পরীক্ষা ছিল 30 কেবি) ।
কলিন ডিন

2
সুন্দর। এর থেকে বড় ইনপুটগুলি পড়তে একটি মার্জিত সমাধানের জন্য সংগ্রাম করা হয়েছে Runtime.exec()। এই নখ।
পাভেল লেচেভ

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