문자열로 OutputStream 가져 오기


580

java.io.OutputStream의 출력을 Java의 String으로 파이프하는 가장 좋은 방법은 무엇입니까?

방법이 있다고 가정 해보십시오.

  writeToStream(Object o, OutputStream out)

객체에서 특정 스트림으로 특정 데이터를 씁니다. 그러나 가능한 한 쉽게이 출력을 문자열로 가져 오려고합니다.

다음과 같은 클래스를 작성하는 것을 고려하고 있습니다.

class StringOutputStream extends OutputStream {

  StringBuilder mBuf;

  public void write(int byte) throws IOException {
    mBuf.append((char) byte);
  }

  public String getString() {
    return mBuf.toString();
  }
}

그러나 더 좋은 방법이 있습니까? 테스트 만하고 싶습니다!


6
ASCII 바이트 만 있습니까? 코드 페이지가 필요하지 않습니까?
Horcrux7

이 경우에 그렇습니다. 그러나 좋은 지적-나는 그것에 대해 생각하지 않았습니다.
Adrian Mouat

답변:


607

나는을 사용할 것이다 ByteArrayOutputStream. 그리고 당신은 전화를 할 수 있습니다 :

new String( baos.toByteArray(), codepage );

또는 더 나은 :

baos.toString( codepage );

를 들어 String생성자는이 codepage수 있습니다 String또는 인스턴스 java.nio.charset.Charset을 . 가능한 값은 java.nio.charset.StandardCharsets.UTF_8 입니다.

방법은 toString()만 수락 StringA와 codepage매개 변수 (자바 8 스탠드).


8
ByteArrayOutputStream에는 toArray () 메소드가 없습니다. 그래도 toByteArray ()가 있습니다. 답을 고칠 수 있습니까? 또한 약간 더 간단한 baos.toString (String charsetName)을 사용하지 않는 것이 좋습니다.
Jonik 2016 년

35
바이트 배열은 이진 데이터입니다. (유니 코드) 텍스트는 여러 가지 방법으로 이진으로 인코딩 될 수 있으므로 ByteArrayOutputStream은 바이트를 인코딩하는 데 사용 된 인코딩을 알아야하므로 동일한 인코딩을 사용하여 바이트를 문자열로 다시 디코딩 할 수 있습니다. 인수없이 toString을 사용하는 것만으로는 문제를 해결하는 대신 문제를 무시하기 때문에 현명하지 않습니다. Java는 플랫폼 인코딩을 사용하여 정확하거나 그렇지 않을 수 있습니다. 기본적으로 무작위입니다. 텍스트를 바이트로 작성하고 해당 인코딩을 toString에 전달하는 데 사용 된 인코딩을 찾아야합니다.
Stijn de Witt

10
여기에 참조 된 코드 페이지를 간단히 설명하면 다음과 같습니다. Java에서는 Charset.defaultCharset () 또는 Charset.forName ( "specific charset"); 나를 위해 일한 것은 : new String (baos.toByteArray (), Charset.defaultCharset ());
월리스 브라운

7
@WallaceBrown을 사용하는 defaultCharset것이 문자셋을 모두 무시하는 것보다 낫지는 않습니다. 사용하기 전에 그것이 무엇인지 알아 내야합니다toString
artbristol

4
StandardCharsets.UTF_8Charset아닙니다 String. 또한이 매개 변수는 charsetName아닌 이라고 codepage합니다.
OrangeDog

46

나는 Apache Commons IO 라이브러리를 좋아한다. 뿐만 아니라 메소드 가있는 ByteArrayOutputStream 버전을 살펴보십시오 . Commons 프로젝트와 같은 기존의 신뢰할 수있는 컴포넌트를 사용하면 코드를 더 작고 쉽게 확장하고 용도를 ​​변경할 수 있습니다.toString(String enc)toByteArray()


10
일 년의 삶을 구하고 모든 공용 API를 읽으십시오. 문제가 발생하면 완전히 테스트되고 커뮤니티가 소유 한 솔루션을 활용할 수 있습니다.
Bob Herrmann

15
흠, 나는 열렬한 Apache Commons 사용자이지만이 경우 JDK 자체 java.io.ByteArrayOutputStream 대신 Commons IO의 ByteArrayOutputStream을 사용해야하는 이유를 알 수 없습니다. 후자는 toString (String charsetName) 및 toByteArray () 메소드도 제공합니다. 정교하게 관리?
Jonik

1
예, 원래 컨텍스트는 콘텐츠를 스트리밍하고 추출하는 더 좋은 방법이므로 Commons IO 예제에는 OutputStream을 채우기 위해 정의 할 수없는 / 의심 할 수있는 메커니즘에 대한 'write (InputStream)'메서드가 포함되어 있기 때문에 Commons IO 예제를 포함 시켰습니다. 나는 또한 JDK와 함께 갈 것이다.
Joe Liversedge 2016 년

23

이것은 잘 작동했습니다

OutputStream output = new OutputStream() {
    private StringBuilder string = new StringBuilder();

    @Override
    public void write(int b) throws IOException {
        this.string.append((char) b );
    }

    //Netbeans IDE automatically overrides this toString()
    public String toString() {
        return this.string.toString();
    }
};

메소드 호출 = >> marshaller.marshal( (Object) toWrite , (OutputStream) output);

그런 다음 문자열을 인쇄하거나 "출력"스트림 자체를 참조하십시오. 예를 들어 문자열을 콘솔에 인쇄하려면 = >> System.out.println(output);

참고 : 내 메서드 호출 marshaller.marshal(Object,Outputstream)은 XML 작업을위한 것입니다. 이 주제와 관련이 없습니다.

이것은 프로덕션 용도로는 매우 낭비이며 변환 방법이 너무 많으며 약간 느슨합니다. 이것은 사용자 정의 OuputStream을 만들고 문자열을 출력하는 것이 가능하다는 것을 증명하기 위해 방금 코딩되었습니다. 그러나 Horcrux7 방식으로 이동하면 단 두 번의 메소드 호출로 모두 좋습니다.

그리고 세상은 또 다른 날에 산다 ....


9
바이트를 char로 캐스팅하면 ascii에서만 작동합니다. Horcrux7과 같은 ByteArrayOutputStream 사용
Dave Ray

2
Dave Ray와 동의 함. 바이트가 ASCII 문자라고 가정 할 수 없습니다. 인코딩을 사용하여 바이트를 해석해야합니다. byteArrayOutputStream.toString ( "UTF-8") 또는 new String (byteArrayOutputStream.toByteArray (), "UTF-8")을 사용하십시오.
Martin Dow

16

내가 한 일은 다음과 같습니다.

Obj.writeToStream(toWrite, os);
try {
    String out = new String(os.toByteArray(), "UTF-8");
    assertTrue(out.contains("testString"));
} catch (UnsupportedEncondingException e) {
    fail("Caught exception: " + e.getMessage());
}

여기서 os는입니다 ByteArrayOutputStream.


2
@JavaJigs 나는 거의 5 년 전에 내 대답의 맨 아래에 이것을 분명히했다 :)
Adrian Mouat

19
교체 고려 "UTF-8"와 함께 StandardCharsets.UTF_8.
james.garriss

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