scala - स्कैला में पूरी फाइल पढ़ें?




(12)

(संपादित करें: यह स्कैला 2.9 में काम नहीं करता है और शायद 2.8 नहीं)

ट्रंक का प्रयोग करें:

scala> io.File("/etc/passwd").slurp
res0: String = 
##
# User Database
# 
... etc

स्कैला में पूरी फाइल को स्मृति में पढ़ने के लिए एक सरल और कैननिक तरीका क्या है? (आदर्श रूप से, चरित्र एन्कोडिंग पर नियंत्रण के साथ।)

सबसे अच्छा मैं साथ आ सकता हूं:

scala.io.Source.fromPath("file.txt").getLines.reduceLeft(_+_)

या मैं जावा के भगवान-भयानक मुहावरों में से एक का उपयोग करना चाहता हूं, जिनमें से सर्वश्रेष्ठ (बाहरी पुस्तकालय का उपयोग किए बिना) ऐसा लगता है:

import java.util.Scanner
import java.io.File
new Scanner(new File("file.txt")).useDelimiter("\\Z").next()

मेलिंग सूची चर्चाओं को पढ़ने से, यह मुझे स्पष्ट नहीं है कि scala.io.Source को कैननिकल I / O लाइब्रेरी भी माना जाता है। मुझे समझ में नहीं आता कि इसका उद्देश्य क्या है, बिल्कुल।

... मुझे कुछ मृत-सरल और याद रखना आसान लगेगा। उदाहरण के लिए, इन भाषाओं में मुहावरे को भूलना बहुत मुश्किल है ...

Ruby    open("file.txt").read
Ruby    File.read("file.txt")
Python  open("file.txt").read()

Scala.io पर GetLines () का उपयोग करना। स्रोत रद्द करता है कि लाइन टर्मिनेटर के लिए कौन से वर्णों का उपयोग किया गया था (\ n, \ r, \ r \ n, आदि)

निम्नलिखित को चरित्र के लिए चरित्र को संरक्षित करना चाहिए, और अत्यधिक स्ट्रिंग कॉन्सटेनेशन (प्रदर्शन समस्याएं) नहीं करता है:

def fileToString(file: File, encoding: String) = {
  val inStream = new FileInputStream(file)
  val outStream = new ByteArrayOutputStream
  try {
    var reading = true
    while ( reading ) {
      inStream.read() match {
        case -1 => reading = false
        case c => outStream.write(c)
      }
    }
    outStream.flush()
  }
  finally {
    inStream.close()
  }
  new String(outStream.toByteArray(), encoding)
}

आपको हर पंक्ति को पार्स करने की आवश्यकता नहीं है और फिर उन्हें दोबारा जोड़ना है ...

Source.fromFile(path)(Codec.UTF8).mkString

मैं इसका उपयोग करना पसंद करता हूं:

import scala.io.{BufferedSource, Codec, Source}
import scala.util.Try

def readFileUtf8(path: String): Try[String] = Try {
  val source: BufferedSource = Source.fromFile(path)(Codec.UTF8)
  val content = source.mkString
  source.close()
  content
}

एक (बड़ी) फ़ाइल को तेजी से पढ़ने / अपलोड करने के लिए, उदाहरण के लिए bufferSize आकार ( Source.DefaultBufSize सेट 2048 ) के आकार को बढ़ाने पर विचार करें,

val file = new java.io.File("myFilename")
io.Source.fromFile(file, bufferSize = Source.DefaultBufSize * 2)

नोट Source.scala । आगे की चर्चा के लिए स्कैला फास्ट टेक्स्ट फ़ाइल को पढ़ें और मेमोरी पर अपलोड करें ।


कॉमन्सियो लाइब्रेरी का उपयोग करते हुए जावा में बस:

FileUtils.readFileToString(file, StandardCharsets.UTF_8)

इसके अलावा, यहां कई जवाब चार्सेट भूल जाते हैं। हमेशा इसे स्पष्ट रूप से प्रदान करना बेहतर होता है, या यह एक दिन मारा जाएगा।


जैसा कि कुछ लोगों ने scala.io.Source का उल्लेख किया है। कनेक्शन रिसाव के कारण scala.io.Source से बचा जाना सर्वोत्तम है।

संभवतः स्केलैक्स और शुद्ध जावा libs जैसे कॉमन्स-आईओ सबसे अच्छे विकल्प हैं जब तक कि नए इनक्यूबेटर प्रोजेक्ट (यानी स्कैला-आईओ) विलय नहीं हो जाता है।


प्रत्येक पंक्ति को मुद्रित करें, जैसे कि जावा बुफर्डर रीडर का उपयोग करें, एवरी लाइन पढ़ें, और इसे प्रिंट करें:

scala.io.Source.fromFile("test.txt" ).foreach{  print  }

बराबर:

scala.io.Source.fromFile("test.txt" ).foreach( x => print(x))

फ़ाइल खोलने और पढ़ने के रूबी सिंटैक्स (और अर्थशास्त्र व्यक्त करें) को अनुकरण करने के लिए, इस निहित वर्ग (स्कैला 2.10 और ऊपरी) पर विचार करें,

import java.io.File

def open(filename: String) = new File(filename)

implicit class RichFile(val file: File) extends AnyVal {
  def read = io.Source.fromFile(file).getLines.mkString("\n")
}

इस तरह,

open("file.txt").read

स्पष्ट सवाल यह है कि "आप पूरी फाइल में क्यों पढ़ना चाहते हैं?" यदि आपकी फाइलें बहुत बड़ी हो तो यह स्पष्ट रूप से स्केलेबल समाधान नहीं है। scala.io.Source आपको getLines विधि से एक Iterator[String] वापस देता है, जो बहुत उपयोगी और संक्षिप्त है।

एक File , एक Reader या एक String InputStream को बदलने के लिए अंतर्निहित जावा आईओ उपयोगिताओं का उपयोग करके एक अंतर्निहित रूपांतरण के साथ आने का कोई काम नहीं है। मुझे लगता है कि स्केलेबिलिटी की कमी का मतलब है कि वे मानक एपीआई में इसे जोड़ने के लिए सही नहीं हैं।


// for file with utf-8 encoding
val lines = scala.io.Source.fromFile("file.txt", "utf-8").getLines.mkString

import scala.io.source
object ReadLine{
def main(args:Array[String]){
if (args.length>0){
for (line <- Source.fromLine(args(0)).getLine())
println(line)
}
}

तर्कों में आप फ़ाइल पथ दे सकते हैं और यह सभी लाइनों को वापस कर देगा


val lines = scala.io.Source.fromFile("file.txt").mkString

वैसे, " scala. " वास्तव में आवश्यक नहीं है, क्योंकि यह हमेशा गुंजाइश में है, और आप निश्चित रूप से, आईओ की सामग्री को पूरी तरह से या आंशिक रूप से आयात कर सकते हैं, और "io" को प्रीपेड करने से बच सकते हैं। भी।

उपर्युक्त फाइल खुली है, हालांकि। समस्याओं से बचने के लिए, आपको इसे इस तरह बंद करना चाहिए:

val source = scala.io.Source.fromFile("file.txt")
val lines = try source.mkString finally source.close()

उपर्युक्त कोड के साथ एक और समस्या यह है कि इसकी कार्यान्वयन प्रकृति के कारण यह बहुत ही धीमी गति से धीमी है। बड़ी फ़ाइलों के लिए एक का उपयोग करना चाहिए:

source.getLines mkString "\n"




scala