স্কালায় একটি ফাইলে কীভাবে লিখবেন?


157

পড়ার জন্য, দরকারী বিমূর্ততা আছে Source। আমি কিভাবে একটি পাঠ্য ফাইলে লাইন লিখতে পারি?


1
আপনি যদি জাভাতে কীভাবে এটি করতে জানেন তবে আপনি স্কালায়ও এটি ব্যবহার করতে পারেন। আপনার প্রশ্নটি কি বিশেষত স্কালার স্ট্যান্ডার্ড লাইব্রেরির সাথে রয়েছে?
Wheaties

1
@ ওহ্যাটিস হ্যাঁ সর্বোত্তম উপায়
স্কেলে

এই গ্রন্থাগারটি সত্যিই ভাল: github.com/pathikrit/better-files
রবিন

Lihaoyi এর OS-Lib গ্রন্থাগার github.com/lihaoyi/os-lib
ওয়েইচিং 清 煒

উত্তর:


71

2019 সম্পাদনা করুন (8 বছর পরে), স্কালা-আইও খুব সক্রিয় নয়, যদি কোনও হয় তবে লি হাওয়ি তার নিজের লাইব্রেরিটি প্রস্তাব করেন lihaoyi/os-lib, যা তিনি নীচে উপস্থাপন করেন

জুন 2019, জাভিয়ের গুইহোট তার উত্তরে গ্রন্থাগারটির উল্লেখ করেছেন Using, স্বয়ংক্রিয় সংস্থান পরিচালনার জন্য একটি উপযোগী।


সম্পাদনা করুন (সেপ্টেম্বর ২০১১): যেহেতু এডুয়ার্ডো কস্তাটি স্কাল ২.৯ সম্পর্কে জিজ্ঞাসা করেছেন, এবং রিক-777 comments মন্তব্য করেছেন যে স্কেল্যাক্স.আইও প্রতিশ্রুতিবদ্ধ ইতিহাসটি ২০০৯ সালের মাঝামাঝি থেকে বেশ অস্তিত্বহীন ...

Scala-আই পরিবর্তিত স্থান নেই: তার দেখতে GitHub রেপো থেকে জেসি Eichar (এছাড়াও তাই ):

স্কোলা আইও ছাতা প্রকল্প আইওর বিভিন্ন দিক এবং বর্ধনের জন্য কয়েকটি উপ প্রকল্প নিয়ে গঠিত।
স্কেলা আইওর দুটি প্রধান উপাদান রয়েছে:

  • কোর - কোর প্রাথমিকভাবে স্বেচ্ছাসেবী উত্স এবং ডুবানো তথ্য থেকে পড়া এবং লেখার সাথে কাজ করে। কোণ পাথর বৈশিষ্ট্যগুলো হয় Input, Outputএবং Seekableযা কোর এপিআই প্রদান।
    অন্যান্য শ্রেণীর গুরুত্বগুলি হ'ল Resource, ReadCharsএবং WriteChars
  • ফাইল - ফাইল হ'ল একটি File( Pathকথিত) API যা জাভা 7 এনআইও ফাইল সিস্টেম এবং এসবিটি পাথফিন্ডার এপিআই এর সংমিশ্রণের উপর ভিত্তি করে is
    Pathএবং FileSystemস্কেলা আইও ফাইল এপিআই-তে প্রধান প্রবেশ পয়েন্ট are
import scalax.io._

val output:Output = Resource.fromFile("someFile")

// Note: each write will open a new connection to file and 
//       each write is executed at the begining of the file,
//       so in this case the last write will be the contents of the file.
// See Seekable for append and patching files
// Also See openOutput for performing several writes with a single connection

output.writeIntsAsBytes(1,2,3)
output.write("hello")(Codec.UTF8)
output.writeStrings(List("hello","world")," ")(Codec.UTF8)

আসল উত্তর (জানুয়ারী ২০১১), স্কেলা-আইও-এর পুরানো জায়গা সহ:

আপনি যদি Scala2.9 এর জন্য অপেক্ষা না করতে চান তবে আপনি স্কেলা -ইনকিউবেটর / স্কেলা-আইও লাইব্রেরিটি ব্যবহার করতে পারেন ।
(" স্কাল উত্স অন্তর্নিহিত ইনপুটস্ট্রিমটি কেন বন্ধ করে না? ") তে উল্লিখিত হিসাবে )

নমুনা দেখুন

{ // several examples of writing data
    import scalax.io.{
      FileOps, Path, Codec, OpenOption}
    // the codec must be defined either as a parameter of ops methods or as an implicit
    implicit val codec = scalax.io.Codec.UTF8


    val file: FileOps = Path ("file")

    // write bytes
    // By default the file write will replace
    // an existing file with the new data
    file.write (Array (1,2,3) map ( _.toByte))

    // another option for write is openOptions which allows the caller
    // to specify in detail how the write should take place
    // the openOptions parameter takes a collections of OpenOptions objects
    // which are filesystem specific in general but the standard options
    // are defined in the OpenOption object
    // in addition to the definition common collections are also defined
    // WriteAppend for example is a List(Create, Append, Write)
    file.write (List (1,2,3) map (_.toByte))

    // write a string to the file
    file.write("Hello my dear file")

    // with all options (these are the default options explicitely declared)
    file.write("Hello my dear file")(codec = Codec.UTF8)

    // Convert several strings to the file
    // same options apply as for write
    file.writeStrings( "It costs" :: "one" :: "dollar" :: Nil)

    // Now all options
    file.writeStrings("It costs" :: "one" :: "dollar" :: Nil,
                    separator="||\n||")(codec = Codec.UTF8)
  }

15
একটি স্কাল 2.9 সংস্করণ সম্পর্কে কি? :)
এডুয়ার্ডো কোস্টার

স্কেলাক্স প্রকল্পটি মারা গেছে বলে মনে হচ্ছে (জুন ২০০৯ থেকে কোনও কমিট করে না)। এটা কী ঠিক? স্কেলাক্স অঙ্গীকারের ইতিহাস
রিক -777

@ এডুয়ার্ডো: আমি স্কেল-আইও লাইব্রেরির জন্য নতুন জায়গাটি দিয়ে আমার উত্তরটি শেষ করেছি (যা স্কাল ২.৯: github.com/jesseeichar/scala-io/issues/20- এর জন্য আপডেট করা হয়েছে )
ভনসি

10
এটি কি আসলে স্কেলার ২.১০ এর জন্য বর্তমান পরামর্শ? স্কাল আইও ব্যবহার করবেন? কোর স্কালায় এখনও কিছু নেই?
ফিল

2
আমি কখনও স্কেলাক্স.আইও ব্যবহার করি নি, তবে এই উদাহরণস্বরূপ লাইনগুলি বিবেচনা করে দেখে মনে হয় এটির API নকশাটি বেশ খারাপ। একটি ইন্টারফেসে চরিত্র এবং বাইনারি ডেটাগুলির জন্য মিশ্রনের পদ্ধতিগুলি সামান্যই বোধগম্য হয় এবং সম্ভবত এটি এনকোডিং বাগগুলি সন্ধান করতে পারে যা খুঁজে পাওয়া শক্ত। Java.io এর ডিজাইন (পাঠক / লেখক বনাম ইনপুট স্ট্রিম / আউটপুট স্ট্রিম) আরও ভাল বলে মনে হচ্ছে।
জ্যাকসাহ্নওয়াল্ড্ট মনিকা

211

এটি স্ট্যান্ডার্ড স্কেল থেকে অনুপস্থিত বৈশিষ্ট্যগুলির মধ্যে একটি যা আমি এতটাই দরকারী পেয়েছি যে আমি এটি আমার ব্যক্তিগত লাইব্রেরিতে যুক্ত করেছি। (আপনার সম্ভবত একটি ব্যক্তিগত গ্রন্থাগারও থাকা উচিত)) কোডটি এরকম হয়:

def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) {
  val p = new java.io.PrintWriter(f)
  try { op(p) } finally { p.close() }
}

এবং এটি এর মতো ব্যবহৃত হয়:

import java.io._
val data = Array("Five","strings","in","a","file!")
printToFile(new File("example.txt")) { p =>
  data.foreach(p.println)
}

1
নতুন java.io.PressWriter () প্ল্যাটফর্মের ডিফল্ট এনকোডিং ব্যবহার করে, যার অর্থ সম্ভবত ফলাফল ফাইলটি খুব পোর্টেবল নয়। উদাহরণস্বরূপ, আপনি যদি এমন কোনও ফাইল তৈরি করতে চান যা আপনি পরে ইমেলের মাধ্যমে প্রেরণ করতে পারেন তবে আপনার সম্ভবত প্রিন্ট রাইটার কনস্ট্রাক্টর ব্যবহার করা উচিত যা আপনাকে একটি এনকোডিং নির্দিষ্ট করতে দেয়।
জ্যাকসাহ্নওয়াল্ড্ট মনিকা

@ জোনাক্রিস্টোফারসাহনওয়াল্ড্ট - অবশ্যই, বিশেষ ক্ষেত্রে আপনি এনকোডিং নির্দিষ্ট করতে চাইতে পারেন। প্ল্যাটফর্মের জন্য ডিফল্ট গড় সবচেয়ে বুদ্ধিমান ডিফল্ট। হিসাবে একই Source(ডিফল্ট দ্বারা ডিফল্ট এনকোডিং)। আপনি অবশ্যই এটি একটি সাধারণ প্রয়োজনীয়তা খুঁজে পাওয়ার enc: Option[String] = Noneপরে অবশ্যই একটি প্যারামিটার যুক্ত করতে পারেন f
রেক্স কের

6
@ রেক্সেরার - আমি একমত নই একটি প্রায় সব ক্ষেত্রেই এনকোডিং নির্দিষ্ট করা উচিত। আমার মুখোমুখি হওয়া বেশিরভাগ এনকোডিং ত্রুটিগুলি ঘটে থাকে কারণ লোকেরা এনকোডিং সম্পর্কে বোঝে না বা ভেবে পায় না। তারা ডিফল্ট ব্যবহার করে এবং এমনকি এটি জানে না কারণ অনেকগুলি এপিআই তাদের এটিকে দূরে সরিয়ে দেয়। আজকাল, সবচেয়ে বুদ্ধিমান ডিফল্ট সম্ভবত ইউটিএফ -8 হবে। হতে পারে আপনি কেবল ইংরেজি এবং অন্যান্য ভাষার সাথে কাজ করেন যা ASCII এ লেখা যেতে পারে। ভাগ্যবান তুমি. আমি জার্মানিতে থাকি এবং মনে রাখার চেয়ে যত্নশীলদের চেয়ে বেশি ভাঙা আমলাতগুলি ঠিক করতে হয়েছিল।
jcsahnwaldt মনিকা

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

সমস্ত ভাঙ্গা উমলাট ঠিক করার জন্য @ জোনাক্রিস্টোফারসাহনওয়াল্ড +10 হাতুড়ি, একটি গর্ত পাঞ্চ ব্যবহার করতে পারবেন না? অথবা তারা ইতিমধ্যে ভরাট হওয়া গর্ত, সম্ভবত এই লোকটি youtube.com/watch?v=E-eBBzWEpwE সহায়তা করতে পারে তবে গম্ভীরভাবে, ASCII এর প্রভাব বিশ্বে এত ক্ষতিকারক, এটি নির্দিষ্ট করা উচিত, এবং ইউটিএফ হিসাবে ডিফল্ট হিসাবে সম্মত হন agree 8
দাভোস

50

রেক্স কেরের উত্তরের মতো, তবে আরও জেনেরিক। প্রথমে আমি একটি সহায়ক ফাংশন ব্যবহার করি:

/**
 * Used for reading/writing to database, files, etc.
 * Code From the book "Beginning Scala"
 * http://www.amazon.com/Beginning-Scala-David-Pollak/dp/1430219890
 */
def using[A <: {def close(): Unit}, B](param: A)(f: A => B): B =
try { f(param) } finally { param.close() }

তারপরে আমি এটি ব্যবহার করি:

def writeToFile(fileName:String, data:String) = 
  using (new FileWriter(fileName)) {
    fileWriter => fileWriter.write(data)
  }

এবং

def appendToFile(fileName:String, textData:String) =
  using (new FileWriter(fileName, true)){ 
    fileWriter => using (new PrintWriter(fileWriter)) {
      printWriter => printWriter.println(textData)
    }
  }

প্রভৃতি


39
আমাকে ভুল করবেন না, আমি আপনার কোডটি পছন্দ করি এবং এটি অত্যন্ত শিক্ষামূলক, তবে সাধারণ সমস্যার জন্য আমি যত বেশি নির্মাণ করি, ততই এটি আমাকে পুরানো "হ্যালো ওয়ার্ল্ড" রসিকতা সম্পর্কে স্মরণ করিয়ে দেয়: ariel.com.au/jokes/The_Evolution_of_a_Programmer .html :-) (আমার কাছ থেকে +1 ভোট)।
গ্রীনল্ডম্যান

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

3
প্রত্যেকেরই কিছু স্তরের অনুশীলন পর্যন্ত "স্কেলা চোখ" থাকবে না - এই কোড উদাহরণটি "বিগিনিং" স্কেলা থেকে আসছে তা মজার বিষয়
অ্যাসিঙ্কয়েট

অ্যাসিঙ্কওয়েট "শুরু" স্ক্যালাল ... এখন পর্যন্ত সর্বাধিক বিদ্রূপযুক্ত শিরোনাম, দ্রষ্টব্য: আমি বইটি করেছি ... এবং এখনই আমি এটি বুঝতে শুরু করেছি ... মনে করি আমি "শিক্ষানবিস" এর আগে এক ধাপ ছিলাম: ডি ........
ব্যবহারকারী 1050817

1
সমস্যাটি এখানে স্কেলার কৌশলগুলি কম, তবে ভার্বোসটি এবং দুর্বল স্টাইল। আমি এটিকে অনেক বেশি পাঠযোগ্য ed আমার রিফ্যাক্টরের পরে এটি মাত্র 4 টি লাইন (ভাল, 4 আইডিই লাইন দৈর্ঘ্যের সাথে স্ক্রিনে ফিট করার জন্য এখানে 6 টি ব্যবহৃত)। আইএমএইচও এটি এখন খুব সুন্দর উত্তর।
সামতিবেস্ট

38

একটি সহজ উত্তর:

import java.io.File
import java.io.PrintWriter

def writeToFile(p: String, s: String): Unit = {
    val pw = new PrintWriter(new File(p))
    try pw.write(s) finally pw.close()
  }

1
@ সাম্তেবেস্ট আপনি কি গ্রন্থাগারগুলি যুক্ত করতে পারবেন import?
ড্যানিয়েল

1
জাভা 7 হিসাবে, পরিবর্তে java.nio.file ব্যবহার করুন: Def WritToFile (ফাইল: স্ট্রিং, স্ট্রিংটোইরাইট: স্ট্রিং): ইউনিট = {ভাল লেখক = ফাইলস.নেউব্ফারড্রাইটার (পাথস.জেট (ফাইল)) Writer.write (স্ট্রিংটোওরাইট) অবশেষে চেষ্টা করুন Writer.close ()}

20

অন্য একটি উত্তর দেওয়া হচ্ছে, কারণ আমার অন্যান্য উত্তরগুলির সম্পাদনাগুলি যেখানে প্রত্যাখ্যান করা হয়েছে।

এটি সবচেয়ে সংক্ষিপ্ত এবং সাধারণ উত্তর (গ্যারেট হলের অনুরূপ)

File("filename").writeAll("hello world")

এটি Jus12 এর মতো, তবে ভার্বোসটি ছাড়াই এবং সঠিক কোড স্টাইল সহ

def using[A <: {def close(): Unit}, B](resource: A)(f: A => B): B =
  try f(resource) finally resource.close()

def writeToFile(path: String, data: String): Unit = 
  using(new FileWriter(path))(_.write(data))

def appendToFile(path: String, data: String): Unit =
  using(new PrintWriter(new FileWriter(path, true)))(_.println(data))

নোট করুন যে আপনার জন্য কোঁকড়া ধনুর্বন্ধনী try finallyবা ল্যাম্বডাসের প্রয়োজন নেই এবং স্থানধারক সিনট্যাক্সের নোট ব্যবহারের প্রয়োজন নেই। আরও ভাল নামকরণ নোট করুন।


2
দুঃখিত, তবে আপনার কোডটি কল্পনাযোগ্য, এটি implementedপূর্বশর্তটি পূরণ করে না । যে কোডটি প্রয়োগ করা হয়নি তা আপনি ব্যবহার করতে পারবেন না। আমি বোঝাতে চাইছি যে এটি ডিফল্টরূপে উপলভ্য নয় এবং সুপরিচিত নয় বলে আপনাকে এটি কীভাবে সন্ধান করতে হবে must
Val,

15

স্কালা সংকলক লাইব্রেরি ব্যবহার করে এখানে একটি সংক্ষিপ্ত ওয়ান-লাইনার দেওয়া হয়েছে:

scala.tools.nsc.io.File("filename").writeAll("hello world")

বিকল্পভাবে, আপনি যদি জাভা লাইব্রেরি ব্যবহার করতে চান তবে আপনি এই হ্যাকটি করতে পারেন:

Some(new PrintWriter("filename")).foreach{p => p.write("hello world"); p.close}

কি আমদানি? অর্থাৎ ফাইল কোথা থেকে আসছে?
বেন হাচিসন

স্কালা সংকলক গ্রন্থাগার
গ্যারেট হল

3
আর টেকসই হবে না (স্কেল 2.11 এ নয়)
ব্রেন্ট ফাউস্ট 21

1
আপনি কি বিষয়ে কথা হয়? scala.tools.nsc.io.File("/tmp/myFile.txt")স্কেলা 2.11.8 এ কাজ করে।

1
এটা তোলে scala.reflect.io.File মধ্যে এখন
কিথ Nordstrom

13

সংরক্ষণ / পড়া / থেকে জন্য এক liners, Stringব্যবহার java.nio

import java.nio.file.{Paths, Files, StandardOpenOption}
import java.nio.charset.{StandardCharsets}
import scala.collection.JavaConverters._

def write(filePath:String, contents:String) = {
  Files.write(Paths.get(filePath), contents.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE)
}

def read(filePath:String):String = {
  Files.readAllLines(Paths.get(filePath), StandardCharsets.UTF_8).asScala.mkString
}

এটি বড় ফাইলগুলির জন্য উপযুক্ত নয়, তবে কাজটি করবে।

কিছু লিঙ্ক:

java.nio.file.Files.write
java.lang.String.getBytes
scala.collection.JavaConverters
scala.collection.immutable.List.mkString


এটি বড় ফাইলগুলির জন্য উপযুক্ত নয় কেন?
চেতন ভাসিন

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

10

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

// Make sure working directory exists and is empty
val wd = os.pwd/"out"/"splash"
os.remove.all(wd)
os.makeDir.all(wd)

// Read/write files
os.write(wd/"file.txt", "hello")
os.read(wd/"file.txt") ==> "hello"

// Perform filesystem operations
os.copy(wd/"file.txt", wd/"copied.txt")
os.list(wd) ==> Seq(wd/"copied.txt", wd/"file.txt")

এটা তোলে জন্য এক liners, হয়েছে ফাইলগুলিতে লেখা , ফাইল সংযোজন , ফাইল মুছে যাওয়ার , এবং অন্যান্য অনেক দরকারী / সাধারণ অপারেশন


এই আপডেটের জন্য আপনাকে ধন্যবাদ। সম্মত। আমি আরও উত্তরোত্তর জন্য আপনার উত্তর আমার নিজের উপর রেফারেন্স করেছি।
ভনসি

7

একটি মাইক্রো লাইব্রেরি আমি লিখেছি: https://github.com/pathikrit/better-files

file.appendLine("Hello", "World")

অথবা

file << "Hello" << "\n" << "World"

এখানেও - এই প্রশ্নটি শীর্ষস্থানীয় হিটগুলির মধ্যে একটি, যখন স্কালার সাহায্যে কোনও ফাইল কীভাবে লিখতে হবে তা গুগল করে - এখন আপনার প্রকল্পটি আরও বড় হয়েছে, আপনি নিজের উত্তরটি কিছুটা প্রসারিত করতে চাইতে পারেন?
asac

6

শুরু হচ্ছে Scala 2.13, মানক গ্রন্থাগার ডেডিকেটেড সম্পদ ব্যবস্থাপনা উপযোগ প্রদান করে: Using

এটি এক্ষেত্রে সংস্থান হিসাবে ব্যবহার করা যেতে পারে যেমন কোনও ফাইলটিতে লেখার জন্য প্রসারিত এবং PrintWriterবা যাই হোক না কেন, পরে উত্সটি বন্ধ করুন:BufferedWriterAutoCloseable

  • উদাহরণস্বরূপ, java.ioএপিআই সহ:

    import scala.util.Using, java.io.{PrintWriter, File}
    
    // val lines = List("hello", "world")
    Using(new PrintWriter(new File("file.txt"))) {
      writer => lines.foreach(writer.println)
    }
  • বা java.nioএপিআই সহ:

    import scala.util.Using, java.nio.file.{Files, Paths}, java.nio.charset.Charset
    
    // val lines = List("hello", "world")
    Using(Files.newBufferedWriter(Paths.get("file.txt"), Charset.forName("UTF-8"))) {
      writer => lines.foreach(line => writer.write(line + "\n"))
    }

6

2019 / সেপ্টেম্বর / 01 এ আপডেট করুন:

  • স্কেল ২.১ Start দিয়ে শুরু করে, স্কালা.ইটি.ল ইউজ করা পছন্দ করুন
  • ফিক্সড বাগ যেখানে finallyমূল গেলা হবে Exceptionদ্বারা নিক্ষিপ্ত tryযদি finallyকোড একটি ছুড়ে ফেলেException

স্ক্যালায় সহজেই কোনও ফাইল কীভাবে লিখতে হয় এবং এইগুলির মধ্যে কয়েকটি বেশ চমৎকার তা নিয়ে এই সমস্ত উত্তরগুলির পর্যালোচনা করার পরে আমার তিনটি বিষয় ছিল:

  1. ইন Jus12 এর উত্তর ব্যবহার সাহায্যকারী পদ্ধতির জন্য সংবাহন ব্যবহার Scala / FP নতুনদের জন্য অ সুস্পষ্ট
  2. এর সাথে নিম্ন স্তরের ত্রুটিগুলি encapsulate প্রয়োজন scala.util.Try
  3. স্ক্রোল / এফপি-তে কীভাবে জাভা বিকাশকারীকে নতুনভাবে দেখানোর প্রয়োজন, যাতে নির্ভরযোগ্য সংস্থানগুলিতে কীভাবে সঠিকভাবে বাসা বাঁধতে হয় closeপদ্ধতিটি প্রতিটি নির্ভরশীল সংস্থার উপর বিপরীত ক্রমে সঞ্চালিত হয় - দ্রষ্টব্য: বিপর্যয়ের সাথে নির্ভরশীল সংস্থানগুলি বন্ধ করা বিশেষত একটি ব্যর্থতার ঘটনায় খুব কমই বোঝা প্রয়োজন যে java.lang.AutoCloseableস্পেসিফিকেশনটি খুব ক্ষতিকারক এবং বাগগুলি খুঁজে পেতে এবং সময় ব্যর্থতা চালাতে অসুবিধা দেখা দেয়

শুরু করার আগে, আমার লক্ষ্য সংক্ষিপ্ততা নয়। এটি স্কালা / এফপি প্রাথমিকভাবে জাভা থেকে আগতদের জন্য সহজ বোঝার সুবিধার্থে। একেবারে শেষে, আমি সমস্ত বিট একসাথে টানবো, এবং তারপরে সংক্ষিপ্ততা বাড়িয়ে দেব।

প্রথমত, ব্যবহারের জন্য usingপদ্ধতিটি আপডেট করা দরকার Try(আবার, সংক্ষিপ্ততা এখানে লক্ষ্য নয়)। এটি নামকরণ করা হবে tryUsingAutoCloseable:

def tryUsingAutoCloseable[A <: AutoCloseable, R]
  (instantiateAutoCloseable: () => A) //parameter list 1
  (transfer: A => scala.util.Try[R])  //parameter list 2
: scala.util.Try[R] =
  Try(instantiateAutoCloseable())
    .flatMap(
      autoCloseable => {
        var optionExceptionTry: Option[Exception] = None
        try
          transfer(autoCloseable)
        catch {
          case exceptionTry: Exception =>
            optionExceptionTry = Some(exceptionTry)
            throw exceptionTry
        }
        finally
          try
            autoCloseable.close()
          catch {
            case exceptionFinally: Exception =>
              optionExceptionTry match {
                case Some(exceptionTry) =>
                  exceptionTry.addSuppressed(exceptionFinally)
                case None =>
                  throw exceptionFinally
              }
          }
      }
    )

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

এর পরে, আমাদের একটি পদ্ধতি তৈরি করতে tryPrintToFileহবে, যা একটি তৈরি করে (বা একটি বিদ্যমান ওভাররাইট) তৈরি করবে Fileএবং একটি লিখবে List[String]। এটা একটা ব্যবহার FileWriterযা দ্বারা encapsulated হয় BufferedWriterযা দ্বারা encapsulated ঘুরে হয় PrintWriter। এবং কর্মক্ষমতা উন্নত করতে ডিফল্ট বাফার আকারটি ডিফল্টের চেয়ে অনেক বড় আকারে BufferedWriterসংজ্ঞায়িত করা defaultBufferSizeহয় এবং 65536 মান নির্ধারিত হয়।

এখানে কোড (এবং আবার, সংক্ষিপ্ততা এখানে লক্ষ্য নয়):

val defaultBufferSize: Int = 65536

def tryPrintToFile(
  lines: List[String],
  location: java.io.File,
  bufferSize: Int = defaultBufferSize
): scala.util.Try[Unit] = {
  tryUsingAutoCloseable(() => new java.io.FileWriter(location)) { //this open brace is the start of the second curried parameter to the tryUsingAutoCloseable method
    fileWriter =>
      tryUsingAutoCloseable(() => new java.io.BufferedWriter(fileWriter, bufferSize)) { //this open brace is the start of the second curried parameter to the tryUsingAutoCloseable method
        bufferedWriter =>
          tryUsingAutoCloseable(() => new java.io.PrintWriter(bufferedWriter)) { //this open brace is the start of the second curried parameter to the tryUsingAutoCloseable method
            printWriter =>
              scala.util.Try(
                lines.foreach(line => printWriter.println(line))
              )
          }
      }
  }
}

উপরের tryPrintToFileপদ্ধতিটি এতে কার্যকর যে এটি একটি List[String]ইনপুট হিসাবে নেয় এবং এটিকে প্রেরণ করে File। আসুন এখন একটি tryWriteToFileপদ্ধতি তৈরি করুন যা একটি নেয় Stringএবং এটিকে এটি লিখে দেয় File

এখানে কোড (এবং আমি আপনাকে এখানে সংক্ষিপ্ততার অগ্রাধিকার অনুমান করতে দেব):

def tryWriteToFile(
  content: String,
  location: java.io.File,
  bufferSize: Int = defaultBufferSize
): scala.util.Try[Unit] = {
  tryUsingAutoCloseable(() => new java.io.FileWriter(location)) { //this open brace is the start of the second curried parameter to the tryUsingAutoCloseable method
    fileWriter =>
      tryUsingAutoCloseable(() => new java.io.BufferedWriter(fileWriter, bufferSize)) { //this open brace is the start of the second curried parameter to the tryUsingAutoCloseable method
        bufferedWriter =>
          Try(bufferedWriter.write(content))
      }
  }
}

অবশেষে, এ Fileহিসাবে একটি হিসাবে লিখিত সামগ্রী আনতে সক্ষম হওয়া দরকারী String। যদিও scala.io.Sourceসহজেই একটি বিষয়বস্তু পাওয়ার জন্য একটি সুবিধাজনক পদ্ধতি প্রদান করে File, closeপদ্ধতির উপর ব্যবহার করা আবশ্যক Sourceঅন্তর্নিহিত জেভিএম ও ফাইল-সিস্টেম হ্যান্ডলগুলি মুক্তি। যদি এটি সম্পন্ন না করা হয়, তবে জেভিএম জিসি (আবর্জনা সংগ্রাহক) Sourceইনস্ট্যান্সটি প্রকাশ করার সময় না পাওয়া পর্যন্ত রিসোর্সটি প্রকাশ করা হবে না । এবং তারপরেও, কেবলমাত্র দুর্বল জেভিএম গ্যারান্টি রয়েছে যে finalizeপদ্ধতিটি জিসি দ্বারা closeসংস্থানটিতে ডাকা হবে । এর অর্থ হল যে ক্লায়েন্টের স্পষ্টভাবে closeপদ্ধতিটি কল করা তার দায়িত্ব , ঠিক যেমন কোনও ক্লায়েন্টের closeউদাহরণ যেমন লম্বা করা তার দায়িত্বjava.lang.AutoCloseable। এর জন্য, আমাদের ব্যবহার পদ্ধতিটি যা পরিচালনা করে তার একটি দ্বিতীয় সংজ্ঞা প্রয়োজন scala.io.Source

এটির জন্য কোডটি এখানে (এখনও সংক্ষিপ্ত হচ্ছে না):

def tryUsingSource[S <: scala.io.Source, R]
  (instantiateSource: () => S)
  (transfer: S => scala.util.Try[R])
: scala.util.Try[R] =
  Try(instantiateSource())
    .flatMap(
      source => {
        var optionExceptionTry: Option[Exception] = None
        try
          transfer(source)
        catch {
          case exceptionTry: Exception =>
            optionExceptionTry = Some(exceptionTry)
            throw exceptionTry
        }
        finally
          try
            source.close()
          catch {
            case exceptionFinally: Exception =>
              optionExceptionTry match {
                case Some(exceptionTry) =>
                  exceptionTry.addSuppressed(exceptionFinally)
                case None =>
                  throw exceptionFinally
              }
          }
      }
    )

এবং এখানে একটি সুপার সিম্পল স্ট্রিমিং ফাইল রিডারে এটির উদাহরণ উদাহরণ রয়েছে (বর্তমানে ডাটাবেস আউটপুট থেকে ট্যাব-বিস্মৃত ফাইলগুলি পড়তে ব্যবহার করে):

def tryProcessSource(
    file: java.io.File
  , parseLine: (String, Int) => List[String] = (line, index) => List(line)
  , filterLine: (List[String], Int) => Boolean = (values, index) => true
  , retainValues: (List[String], Int) => List[String] = (values, index) => values
  , isFirstLineNotHeader: Boolean = false
): scala.util.Try[List[List[String]]] =
  tryUsingSource(scala.io.Source.fromFile(file)) {
    source =>
      scala.util.Try(
        ( for {
            (line, index) <-
              source.getLines().buffered.zipWithIndex
            values =
              parseLine(line, index)
            if (index == 0 && !isFirstLineNotHeader) || filterLine(values, index)
            retainedValues =
              retainValues(values, index)
          } yield retainedValues
        ).toList //must explicitly use toList due to the source.close which will
                 //occur immediately following execution of this anonymous function
      )
  )

উপরের ফাংশনটির একটি আপডেট সংস্করণ একটি পৃথক তবে সম্পর্কিত স্ট্যাকওভারফ্লো প্রশ্নের উত্তর হিসাবে সরবরাহ করা হয়েছে ।


এখন, এগুলি আমদানির সাথে একত্রিত করে (একটি টেক্সট সম্পাদকের সাহায্যে ডেস্কটপে আউটপুট ডাম্পকে আরও সহজে পরীক্ষা করা সহজতর করার জন্য Eclipse ScalaIDE এবং IntelliJ Scala উভয় প্লাগইনে উপস্থিত স্কাল ওয়ার্কশিটে পেস্ট করা আরও সহজ করে তোলে), কোডটি দেখতে এটির মতো (বর্ধিত সংক্ষিপ্ততার সাথে):

import scala.io.Source
import scala.util.Try
import java.io.{BufferedWriter, FileWriter, File, PrintWriter}

val defaultBufferSize: Int = 65536

def tryUsingAutoCloseable[A <: AutoCloseable, R]
  (instantiateAutoCloseable: () => A) //parameter list 1
  (transfer: A => scala.util.Try[R])  //parameter list 2
: scala.util.Try[R] =
  Try(instantiateAutoCloseable())
    .flatMap(
      autoCloseable => {
        var optionExceptionTry: Option[Exception] = None
        try
          transfer(autoCloseable)
        catch {
          case exceptionTry: Exception =>
            optionExceptionTry = Some(exceptionTry)
            throw exceptionTry
        }
        finally
          try
            autoCloseable.close()
          catch {
            case exceptionFinally: Exception =>
              optionExceptionTry match {
                case Some(exceptionTry) =>
                  exceptionTry.addSuppressed(exceptionFinally)
                case None =>
                  throw exceptionFinally
              }
          }
      }
    )

def tryUsingSource[S <: scala.io.Source, R]
  (instantiateSource: () => S)
  (transfer: S => scala.util.Try[R])
: scala.util.Try[R] =
  Try(instantiateSource())
    .flatMap(
      source => {
        var optionExceptionTry: Option[Exception] = None
        try
          transfer(source)
        catch {
          case exceptionTry: Exception =>
            optionExceptionTry = Some(exceptionTry)
            throw exceptionTry
        }
        finally
          try
            source.close()
          catch {
            case exceptionFinally: Exception =>
              optionExceptionTry match {
                case Some(exceptionTry) =>
                  exceptionTry.addSuppressed(exceptionFinally)
                case None =>
                  throw exceptionFinally
              }
          }
      }
    )

def tryPrintToFile(
  lines: List[String],
  location: File,
  bufferSize: Int = defaultBufferSize
): Try[Unit] =
  tryUsingAutoCloseable(() => new FileWriter(location)) { fileWriter =>
    tryUsingAutoCloseable(() => new BufferedWriter(fileWriter, bufferSize)) { bufferedWriter =>
      tryUsingAutoCloseable(() => new PrintWriter(bufferedWriter)) { printWriter =>
          Try(lines.foreach(line => printWriter.println(line)))
      }
    }
  }

def tryWriteToFile(
  content: String,
  location: File,
  bufferSize: Int = defaultBufferSize
): Try[Unit] =
  tryUsingAutoCloseable(() => new FileWriter(location)) { fileWriter =>
    tryUsingAutoCloseable(() => new BufferedWriter(fileWriter, bufferSize)) { bufferedWriter =>
      Try(bufferedWriter.write(content))
    }
  }

def tryProcessSource(
    file: File,
  parseLine: (String, Int) => List[String] = (line, index) => List(line),
  filterLine: (List[String], Int) => Boolean = (values, index) => true,
  retainValues: (List[String], Int) => List[String] = (values, index) => values,
  isFirstLineNotHeader: Boolean = false
): Try[List[List[String]]] =
  tryUsingSource(() => Source.fromFile(file)) { source =>
    Try(
      ( for {
          (line, index) <- source.getLines().buffered.zipWithIndex
          values = parseLine(line, index)
          if (index == 0 && !isFirstLineNotHeader) || filterLine(values, index)
          retainedValues = retainValues(values, index)
        } yield retainedValues
      ).toList
    )
  }

স্কেল / এফপি নবাগত হিসাবে, আমি উপরের জ্ঞান এবং সমাধানগুলি অর্জন করে বেশিরভাগ ঘন্টা (বেশিরভাগ মাথা-ঘামাচি হতাশায়) পোড়া করেছি। আমি আশা করি এটি অন্যান্য স্কালা / এফপি নবজাতকদের এই বিশেষ শিক্ষার কুঁচকে দ্রুত অর্জন করতে সহায়তা করে।


2
অবিশ্বাস্য আপডেট। একমাত্র সমস্যাটি হ'ল এখন আপনার কাছে 100 লাইনের কোড রয়েছে যা দিয়ে প্রতিস্থাপন করা যেতে পারে try-catch-finally। এখনও আপনার আবেগ ভালবাসা।
পর্যবেক্ষক

1
@ অবজারভার আমি দৃ as়ভাবে বলতে চাই যে এটি একটি ভুল বিবৃতি। আমি যে প্যাটার্নটির বর্ণনা দিচ্ছি তা হ'ল একটি ক্লায়েন্টকে অবশ্যই বয়লারপ্লেটের পরিমাণ হ্রাস করতে হবে অটোক্লিজেবলগুলি বন্ধ করার সঠিক পরিচালনা নিশ্চিত করতে গিয়ে স্কালা.ইটিল.ট্রি ব্যবহারের স্কালা আইডিয়োমেটিক এফপি প্যাটার্ন সক্ষম করে। যদি আপনি নিজে চেষ্টা / ক্যাচ / অবশেষে ব্লকগুলি লিখে ম্যানুয়ালি করে একই প্রভাবগুলি অর্জন করার চেষ্টা করেন তবে আমি মনে করি আপনি কল্পনা করার চেয়ে বেশ খানিকটা বেশি বয়লারপ্লেট দিয়ে শেষ করবেন। সুতরাং, সমস্ত বয়লারপ্লেট স্কালা ফাংশনের 100 লাইনে ঠেলাতে উল্লেখযোগ্য পাঠযোগ্যতার মান রয়েছে।
বিশৃঙ্খলা

1
যদি এটি কোনও উপায়ে আক্রমণাত্মক মনে হয় তবে দুঃখিত। তবুও, আমার বক্তব্যটি হ'ল এ জাতীয় পরিমাণের কোডের প্রয়োজন নেই, কারণ এটি আরও অনেক সরলতার সাথে অ-কার্যকরী পদ্ধতির মাধ্যমে অর্জন করা যেতে পারে। ব্যক্তিগতভাবে, আমি চেষ্টা করেছি শেষ পর্যন্ত কিছু অতিরিক্ত চেক দিয়ে। এটি কেবল খাটো। যদি আমি মোড়ক ব্যবহার করতে চাইতাম তবে সমস্ত নোংরা কাজটি ব্যবহার করার জন্য অ্যাপাচি ইউটিলস রয়েছে। আরও, সমস্ত মানক পাঠক / লেখকরা অন্তর্নিহিত স্ট্রিমগুলি ঘনিষ্ঠ করে তাই আপনার মাল্টিপ্রেপের প্রয়োজন হয় না। PS: আমি আপনার প্রচেষ্টা সমর্থন করার জন্য আমার ভোট বিয়োগ থেকে এক থেকে আরও একতে পরিবর্তন করেছি। সুতরাং, দয়া করে, আমাকে খারাপ উদ্দেশ্য সম্পর্কে সন্দেহ করবেন না।
পর্যবেক্ষক

কোন অপরাধ নেওয়া হয়নি।
বিশৃঙ্খলা

1
আমি আপনার দৃষ্টিভঙ্গি বুঝতে পারি। আলোচনার জন্য ধন্যবাদ, আমাকে এ সম্পর্কে কিছুটা ভাবতে হবে। আপনার দিনটি শুভ হোক!
পর্যবেক্ষক

3

স্ক্যালাজ-স্ট্রিম ব্যবহার করে কোনও ফাইলে কিছু লাইন লেখার উদাহরণ এখানে ।

import scalaz._
import scalaz.stream._

def writeLinesToFile(lines: Seq[String], file: String): Task[Unit] =
  Process(lines: _*)              // Process that enumerates the lines
    .flatMap(Process(_, "\n"))    // Add a newline after each line
    .pipe(text.utf8Encode)        // Encode as UTF-8
    .to(io.fileChunkW(fileName))  // Buffered write to the file
    .runLog[Task, Unit]           // Get this computation as a Task
    .map(_ => ())                 // Discard the result

writeLinesToFile(Seq("one", "two"), "file.txt").run

1

তাঁর আগে সমথিবেষ্ট এবং অবদানকারীদের ছাড়িয়ে যাওয়ার জন্য, আমি নামকরণ এবং সংক্ষিপ্ততার উন্নতি করেছি:

  def using[A <: {def close() : Unit}, B](resource: A)(f: A => B): B =
    try f(resource) finally resource.close()

  def writeStringToFile(file: File, data: String, appending: Boolean = false) =
    using(new FileWriter(file, appending))(_.write(data))

এটি "হাঁসের টাইপিং" ব্যবহার করে যা প্রতিবিম্বের উপর নির্ভর করে। অনেক প্রসঙ্গে, প্রতিবিম্বের উপর নির্ভর করে একটি স্টার্টার নয় is
বিশৃঙ্খল

1

ত্রুটি পরিচালনার সাথে কোনও নির্ভরতা নেই

  • স্ট্যান্ডার্ড লাইব্রেরি থেকে একচেটিয়া পদ্ধতি ব্যবহার করে
  • প্রয়োজনে ফাইলের জন্য ডিরেক্টরি তৈরি করে
  • Eitherত্রুটি পরিচালনার জন্য ব্যবহার করে

কোড

def write(destinationFile: Path, fileContent: String): Either[Exception, Path] =
  write(destinationFile, fileContent.getBytes(StandardCharsets.UTF_8))

def write(destinationFile: Path, fileContent: Array[Byte]): Either[Exception, Path] =
  try {
    Files.createDirectories(destinationFile.getParent)
    // Return the path to the destinationFile if the write is successful
    Right(Files.write(destinationFile, fileContent))
  } catch {
    case exception: Exception => Left(exception)
  }

ব্যবহার

val filePath = Paths.get("./testDir/file.txt")

write(filePath , "A test") match {
  case Right(pathToWrittenFile) => println(s"Successfully wrote to $pathToWrittenFile")
  case Left(exception) => println(s"Could not write to $filePath. Exception: $exception")
}

1

2019 আপডেট:

সংক্ষিপ্তসার - জাভা NIO (বা async জন্য NIO.2) এখনও স্কালায় সমর্থিত সর্বাধিক বিস্তৃত ফাইল প্রসেসিং সমাধান। নিম্নলিখিত কোডটি একটি নতুন ফাইলে কিছু পাঠ্য তৈরি করে এবং লেখায়:

import java.io.{BufferedOutputStream, OutputStream}
import java.nio.file.{Files, Paths}

val testFile1 = Paths.get("yourNewFile.txt")
val s1 = "text to insert in file".getBytes()

val out1: OutputStream = new BufferedOutputStream(
  Files.newOutputStream(testFile1))

try {
  out1.write(s1, 0, s1.length)
} catch {
  case _ => println("Exception thrown during file writing")
} finally {
  out1.close()
}
  1. জাভা লাইব্রেরি আমদানি করুন: আইও এবং এনআইও
  2. Pathআপনার নির্বাচিত ফাইলের নাম সহ একটি অবজেক্ট তৈরি করুন
  3. আপনার পাঠ্যকে আপনি কোনও ফাইলের মধ্যে বাইট অ্যারেতে সন্নিবেশ করতে চান তা রূপান্তর করুন
  4. আপনার ফাইলটি একটি স্ট্রিম হিসাবে পান: OutputStream
  5. আপনার আউটপুট স্ট্রিমের writeফাংশনে আপনার বাইট অ্যারে পাস করুন
  6. স্ট্রিমটি বন্ধ করুন

1

এই উত্তরের অনুরূপ , এখানে একটি উদাহরণ রয়েছে fs2(সংস্করণ 1.0.4):

import cats.effect._

import fs2._
import fs2.io

import java.nio.file._

import scala.concurrent.ExecutionContext
import scala.language.higherKinds
import cats.syntax.functor._

object ScalaApp extends IOApp {

  def write[T[_]](p: Path, s: String)
                 (implicit F: ConcurrentEffect[T], cs: ContextShift[T]): T[Unit] = {
    Stream(s)
      .covary[T]
      .through(text.utf8Encode)
      .through(
        io.file.writeAll(
          p,
          scala.concurrent.ExecutionContext.global,
          Seq(StandardOpenOption.CREATE)
        )
      )
      .compile
      .drain
  }


  def run(args: List[String]): IO[ExitCode] = {

    implicit val executionContext: ExecutionContext =
      scala.concurrent.ExecutionContext.Implicits.global

    implicit val contextShift: ContextShift[IO] =
      IO.contextShift(executionContext)

    val outputFile: Path = Paths.get("output.txt")

    write[IO](outputFile, "Hello world\n").as(ExitCode.Success)

  }
}

0

এই লাইনটি অ্যারে বা স্ট্রিং থেকে একটি ফাইল লিখতে সহায়তা করে।

 new PrintWriter(outputPath) { write(ArrayName.mkString("")); close }

0

আপনার প্রকল্পটিতে যদি আপনি যাইহোক আক্কা স্ট্রিমগুলি নিয়ে থাকেন তবে এটি একটি ওয়ান-লাইনার সরবরাহ করে:

def writeToFile(p: Path, s: String)(implicit mat: Materializer): Unit = {
  Source.single(ByteString(s)).runWith(FileIO.toPath(p))
}

আক্কা ডক্স> স্ট্রিমিং ফাইল আইও

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