스칼라에서 전체 파일을 읽습니까?
스칼라에서 전체 파일을 메모리로 읽는 간단하고 표준적인 방법은 무엇입니까? (이상적으로 문자 인코딩을 제어 할 수 있습니다.)
내가 생각해 낼 수있는 최선은 다음과 같습니다.
scala.io.Source.fromPath("file.txt").getLines.reduceLeft(_+_)
또는 Java의 신형 관용구 중 하나를 사용해야합니까 (외부 라이브러리를 사용하지 않고) 가장 좋은 것은 다음과 같습니다.
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()
val lines = scala.io.Source.fromFile("file.txt").mkString
그건 그렇고, " scala.
"는 항상 범위 내에 있기 때문에 실제로는 필요하지 않으며, 물론 io의 내용을 전체적으로 또는 부분적으로 가져오고 "io"를 앞에 두지 않아도됩니다. 너무.
그러나 위의 파일은 열린 상태로 유지됩니다. 문제를 피하려면 다음과 같이 닫아야합니다.
val source = scala.io.Source.fromFile("file.txt")
val lines = try source.mkString finally source.close()
위의 코드의 또 다른 문제는 구현 특성으로 인해 끔찍하다는 것입니다. 더 큰 파일의 경우 다음을 사용해야합니다.
source.getLines mkString "\n"
Daniel의 솔루션을 확장하기 위해 파일 조작이 필요한 파일에 다음 가져 오기를 삽입하여 작업을 크게 줄일 수 있습니다.
import scala.io.Source._
이를 통해 이제 다음을 수행 할 수 있습니다.
val lines = fromFile("file.txt").getLines
나는 전체 파일을 하나의 파일로 읽는 것에주의 할 것이다 String
. 그것은 당신이 생각하는 것보다 더 빨리 그리고 어려워하는 매우 나쁜 습관입니다. 이 getLines
메소드는 유형의 값을 리턴합니다 Iterator[String]
. 효과적으로 파일에 게으른 커서로 메모리 부족 위험없이 필요한 데이터 만 검사 할 수 있습니다.
아, 그리고 당신의 암묵적 인 질문에 대답하기 위해 Source
: 예, 표준 I / O 라이브러리입니다. 대부분의 코드는 java.io
하위 수준의 인터페이스와 기존 프레임 워크와의 호환성으로 인해 결국 사용 되지만 Source
, 특히 간단한 파일 조작을 위해서는 선택이 가능한 모든 코드를 사용해야합니다 .
// for file with utf-8 encoding
val lines = scala.io.Source.fromFile("file.txt", "utf-8").getLines.mkString
(편집 : 이것은 scala 2.9에서 작동하지 않으며 어쩌면 2.8에서도 작동하지 않습니다)
트렁크 사용 :
scala> io.File("/etc/passwd").slurp
res0: String =
##
# User Database
#
... etc
import java.nio.charset.StandardCharsets._
import java.nio.file.{Files, Paths}
new String(Files.readAllBytes(Paths.get("file.txt")), UTF_8)
문자 인코딩을 제어하고 정리할 리소스가 없습니다. 또한 최적화 될 수 있습니다 (예 : Files.readAllBytes
파일 크기에 적합한 바이트 배열 할당).
Source.fromFile에 문제가 있다고 들었습니다. 개인적으로 Source.fromFile을 사용하여 큰 파일을 여는 데 문제가 있었고 Java InputStreams를 사용해야했습니다.
또 다른 흥미로운 해결책은 scalax를 사용하는 것입니다. 다음은 ManagedResource를 사용하여 scalax 헬퍼가있는 파일을 여는 로그 파일을 여는 주석이 달린 코드의 예입니다. http://pastie.org/pastes/420714
scala.io.Source에서 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)
}
Java와 마찬가지로 CommonsIO 라이브러리를 사용하십시오.
FileUtils.readFileToString(file, StandardCharsets.UTF_8)
또한 많은 답변이 Charset을 잊어 버렸습니다. 항상 명시 적으로 제공하는 것이 좋습니다. 그렇지 않으면 하루가 걸릴 것입니다.
파일을 열고 읽는 Ruby 구문을 에뮬레이션하고 의미를 전달하려면이 암시 적 클래스 (Scala 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
하나 더 : https://github.com/pathikrit/better-files#streams-and-codecs
내용을 메모리에로드하지 않고 파일을 슬러 핑하는 다양한 방법 :
val bytes : Iterator[Byte] = file.bytes
val chars : Iterator[Char] = file.chars
val lines : Iterator[String] = file.lines
val source : scala.io.BufferedSource = file.content
읽기 / 쓰기를 수행하는 모든 작업에 자체 코덱을 제공 할 수 있습니다 (제공하지 않으면 scala.io.Codec.default라고 가정).
val content: String = file.contentAsString // default codec
// custom codec:
import scala.io.Codec
file.contentAsString(Codec.ISO8859)
//or
import scala.io.Codec.string2codec
file.write("hello world")(codec = "US-ASCII")
scala.io.Source를 언급 한 소수의 사람들 은 연결 누출로 인해 피하는 것이 가장 좋습니다.
아마도 새 인큐베이터 프로젝트 (예 : scala-io)가 병합 될 때까지 scalax와 commons-io와 같은 순수 Java 라이브러리가 최상의 옵션입니다.
scala io의 경로를 사용하여 파일을 읽고 처리 할 수도 있습니다.
import scalax.file.Path
이제 다음을 사용하여 파일 경로를 얻을 수 있습니다.
val filePath = Path("path_of_file_to_b_read", '/')
val lines = file.lines(includeTerminator = true)
종료자를 포함 할 수도 있지만 기본적으로 false로 설정되어 있습니다.
(큰) 파일을 전체적으로 빠르게 읽고 업로드하려면 다음과 같이 크기를 bufferSize
(로 Source.DefaultBufSize
설정 2048
) 늘리십시오 .
val file = new java.io.File("myFilename")
io.Source.fromFile(file, bufferSize = Source.DefaultBufSize * 2)
Source.scala 참고 하십시오 . 자세한 내용은 Scala 빠른 텍스트 파일을 읽고 메모리에 업로드를 참조하십시오 .
명백한 질문은 "왜 전체 파일을 읽고 싶습니까?"입니다. 파일이 매우 커지면 확장 가능한 솔루션이 아닙니다. 는 scala.io.Source
당신이를 다시 제공 Iterator[String]
으로부터 getLines
매우 유용하고 간결 방법.
그것은 변환하는 기본 자바 IO 유틸리티를 사용하여 암시 적 변환을 마련하는 작업의 많은 부분이 아니다 File
하는 Reader
또는를 InputStream
A를 String
. 확장 성이 부족하다는 것은 표준 API에 이것을 추가하지 않는 것이 옳다는 것을 의미한다고 생각합니다.
모든 한 줄을 구문 분석 한 다음 다시 연결할 필요가 없습니다 ...
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
}
Java BufferedReader 사용 ervery 행 읽기와 같이 모든 행을 인쇄하고 인쇄하십시오.
scala.io.Source.fromFile("test.txt" ).foreach{ print }
동등한:
scala.io.Source.fromFile("test.txt" ).foreach( x => print(x))
import scala.io.source
object ReadLine{
def main(args:Array[String]){
if (args.length>0){
for (line <- Source.fromLine(args(0)).getLine())
println(line)
}
}
인수로 파일 경로를 지정할 수 있으며 모든 줄을 반환합니다.
타사 종속성이 마음에 들지 않으면 내 OS-Lib 라이브러리 사용을 고려해야 합니다 . 파일 읽기 / 쓰기 및 파일 시스템 작업이 매우 편리합니다.
// 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")
한 줄에 대한 도우미와 바이트를 읽어 , 덩어리를 읽고 , 라인을 읽고 , 많은 다른 유용한 / 일반적인 작업
참고 URL : https://stackoverflow.com/questions/1284423/read-entire-file-in-scala
'Programing' 카테고리의 다른 글
모든 전역 변수 / 지역 변수를 인쇄 하시겠습니까? (0) | 2020.03.14 |
---|---|
Magento에서 간단한 'Hello World'모듈을 어떻게 만듭니 까? (0) | 2020.03.14 |
도메인 이름에 대한 권한이있는 이름 서버는 어떻게 찾습니까? (0) | 2020.03.14 |
텍스트에 대한 개요 효과 (0) | 2020.03.14 |
Subversion에서 커밋되지 않은 변경 사항을 일시적으로 제거하십시오 (일명“git-stash”). (0) | 2020.03.14 |