2008-10-19 13 views
469

Jaki jest najlepszy sposób, aby potokować wyjście z java.io.OutputStream do String w Javie?Pobierz OutputStream na ciąg

że mam metodę:

writeToStream(Object o, OutputStream out) 

który zapisuje pewnych danych z obiektu do danego strumienia. Jednak chcę, aby to wyjście w łańcuchu było jak najłatwiejsze.

Zastanawiam pisząc klasę tak (niesprawdzone):

class StringOutputStream extends OutputStream { 

    StringBuilder mBuf; 

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

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

Ale czy istnieje lepszy sposób? Chcę tylko przeprowadzić test!

+6

Czy masz tylko bajty ASCII? Czy nie potrzebujesz strony kodowej? – Horcrux7

+0

W tym przypadku tak.Jednak punkt dobry - nie myślałem o tym. –

Odpowiedz

514

Chciałbym użyć ByteArrayOutputStream. I wykończenie można nazwać:

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

lub lepiej

baos.toString(codepage); 

Dla konstruktora String codepage może być ciągiem lub instancją java.nio.charset.Charset. Możliwą wartością jest java.nio.charset.StandardCharsets.UTF_8.

Metoda toString przyjmuje tylko ciąg jako parametr codepage (podstawa Java 8).

+7

ByteArrayOutputStream nie ma metody toArray(); ale musi to byćByteArray(). Czy potrafisz naprawić odpowiedź? Również, dlaczego nie użyć baos.toString (String charsetName), co byłoby nieco prostsze. – Jonik

+0

Dzięki za wskazówkę z toString (zestaw znaków). Nigdy nie patrzę na toString, ponieważ spodziewam się ByteArrayOutputStream @ 123456. Poprawiłem również błąd przy pomocy toByteArray(). – Horcrux7

+0

Należy również pamiętać, że niektóre strony kodowe nie są instalowane, chyba że wyraźnie poprosisz o nie w przypadku instalacji niestandardowej. –

40

Lubię bibliotekę IO Apache Commons. Spójrz na jego wersję ByteArrayOutputStream, która ma metodę toString(String enc), a także toByteArray(). Korzystanie z istniejących i zaufanych komponentów, takich jak projekt Commons, pozwala zmniejszyć rozmiar kodu i ułatwić jego rozszerzenie i zmianę przeznaczenia. Powodzenia.

+8

Uratuj się przez rok swojego życia i przeczytaj wszystkie popularne API, więc gdy napotkasz problem, możesz uwolnić w pełni przetestowane i stworzone przez społeczność rozwiązanie. –

+14

Hmm, jestem zagorzałym użytkownikiem Apache Commons, ale w tym przypadku nie widzę powodu, dla którego powinieneś używać ByteArrayOutputStream Commons IO zamiast własnego java.io.ByteArrayOutputStream JDK. Ten ostatni zapewnia również metody toString (String charsetName) i toByteArray(). Możesz rozwinąć temat? – Jonik

+1

Tak, ponieważ oryginalny kontekst był lepszym sposobem na przesyłanie strumieniowe i wyodrębnianie treści, zawarłem przykład Commons IO, ponieważ zawiera on metodę "write (InputStream)" dla nieokreślonego/wątpliwego mechanizmu do wypełniania strumienia OutputStream. Poszedłbym też z JDK. –

11

Oto, co skończyło się robi:

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()); 
} 

Gdzie jest ByteArrayOutputStream os.

+3

Co to jest "os" w twoim kodzie? – Synox

+1

@JavaJigs Wyjaśniłem to na dole mojej odpowiedzi prawie 5 lat temu :) –

+10

Rozważ zastąpienie '' UTF-8' '' StandardCharsets.UTF_8'. –

21

to działało ładnie

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(); 
     } 
    }; 

wywołanie metody = >>marshaller.marshal((Object) toWrite , (OutputStream) output);

następnie wydrukować ciąg lub dostać tylko odwoływać się do „wyjścia” strumień się Jako przykład, aby wydrukować ciąg out na konsolę = >>System.out.println(output);

FYI: moja metoda wywołania marshaller.marshal(Object,Outputstream) służy do pracy z xml. Nie ma to znaczenia dla tego tematu.

Jest to bardzo marnotrawstwo w przypadku zastosowań produkcyjnych, istnieje wiele sposobów na konwersję i jest nieco luźna. Zostało to zakodowane, aby udowodnić ci, że jest całkowicie możliwe utworzenie niestandardowego OuputStream i wyprowadzenie ciągu znaków. Ale po prostu idź ścieżką Horcrux7 i wszystko jest w porządku za pomocą zaledwie dwóch wywołań metod.

A świat żyje w innym dniu ....

+7

Wystarczy rzucić bajt na char działa tylko na ascii. Użyj ByteArrayOutputStream jak Horcrux7 –

+2

Uzgodniono z Dave'em Rayem. Nie można założyć, że twój bajt jest postacią ASCII. Musisz interpretować bajty za pomocą kodowania. Użyj byteArrayOutputStream.toString ("UTF-8") lub nowy ciąg (byteArrayOutputStream.toByteArray(), "UTF-8"). –

-11

Dlaczego nie używasz ByteArrayOutputStream? To właśnie powinieneś użyć w tym celu.

+51

Masz na myśli, jak wszystkie inne odpowiedzi, które są tutaj od ponad 4 lat sugerują? ;) –