스칼라에서 InputStream을 문자열로 변환하는 관용적 방법


111

InputStream을 String으로 변환하기 위해 Java에서 사용한 편리한 기능이 있습니다. 다음은 Scala로 직접 번역 한 것입니다.

  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

Scala> = 2.11의 경우

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

Scala <2.11의 경우 :

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

거의 같은 일을합니다. 그래도 선을 얻은 다음 모두 다시 붙이고 싶은 이유는 확실하지 않습니다. 스트림이 비 차단이라고 가정 할 수 있다면을 사용 .available하고 전체를 바이트 배열로 읽고 그로부터 직접 문자열을 만들 수 있습니다.


2
내가 직접 사용한 한 가지 가능한 이유는 다른 운영 체제에서 줄 끝을 정규화하는 것입니다.
Kevin Wright

Raam의 대답도 훌륭하지만 (약간 더 간결합니다) Rex를 답으로 표시합니다. 라인을 다시 붙이는 것은 몇 가지 경우에 특정했지만,이 코드를 사용하는 것이 적절하지 않은 곳에서이 코드를 사용했음을 상기 시켰습니다.
bballant 2011 년

이 솔루션은 getLines ()를 사용하므로 매우 안전하지 않습니다. 입력 스트림에 "새 줄"문자가 없으면 어떻게됩니까? 그 모든 것은 블록
폴 Sabou

아주 나쁜 해결책입니다. 입력 스트림에 DOS 줄 끝 (\ r \ n)이 포함되어 있으면 어떻게 될까요? 이들은이 방법으로 제거됩니다. 또한 mkString은 버퍼를 사용하지만 문자 블록을 읽는 것이 가장 빠릅니다.
Dibbeke 2014-06-23

1
@RexKerr 답변에서 언급 한 "성능 버그"를 지적 해 주시겠습니까? 몇 가지 기본 테스트 케이스로 두 버전을 모두 테스트했지만 아무 문제도 발생하지 않았습니다.
Sahil Sareen 2015 년

74

Source.fromInputStream(is).mkString("") 증서를 할 것입니다 .....


좋은 지적; 소스는 Iterator[Char].
Rex Kerr

8
이런 일을 할 때 문자 인코딩을 지정하는 것도 일반적으로 좋은 습관입니다. 이를 위해 : Source.fromInputStream(is)(Codec.UTF8).mkString
Connor Doyle

이것은 간결하지만 원래 자바 코드가 그랬던 반면 스트림을 닫지 않습니다.
Rich

@Rich fromInputStream()는 적어도 Scala 2.11에서 스트림을 닫는 것처럼 보입니다.
jaco0646

2
@ jaco0646-스트림을 닫지 않습니다. 방금 테스트했습니다. 이를 증명하는 데모 코드는 다음과 같습니다. gist.github.com/RichardBradley/bcd1a5e61fcc83e4e59f8b9b0bc2301c
Rich

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.
BeepDog 2014 년

3
첫 번째 줄을 건너 뛰고 inputStreamReader메서드로 전달하십시오 .
Kamil Lelonek 2014 년

1
이것은 Scala 2.11.7의 scala.io.Source보다 잠재적으로 훨씬 더 빠릅니다. 나는 그것에 대한 정말 기본적인 벤치 마크를 작성했고 대부분의 경우 큰 파일 (테스트는 ~ 35MB 텍스트 파일)의 경우 약 5 %, 작은 파일의 경우 최대 2,800 % 더 빠릅니다 (테스트는 ~ 30KB). .
Colin Dean

2
아름다운. 에서 큰 입력을 읽는 우아한 솔루션을 위해 고군분투했습니다 Runtime.exec(). 이건 못 박아.
Pavel Lechev

사용할 문자 세트를 어떻게 지정합니까?
wheeler
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.