Byte [] na InputStream lub OutputStream

131

Mam kolumnę blob w mojej tabeli bazy danych, której muszę użyć byte[]w moim programie Java jako mapowania i aby użyć tych danych, muszę przekonwertować je na InputStreamlub OutputStream. Ale nie wiem, co dzieje się wewnętrznie, kiedy to robię. Czy ktoś może mi krótko wyjaśnić, co się dzieje, kiedy dokonuję tej konwersji?

GuruKulki
źródło
2
Czy tytułem nie powinno być „tablica bajtów ...”, „tablica bajtów ...” lub „bajt [] ...” zamiast „bajt tablicy ...”?
kuester2000
1
Zobacz na odwrocie tutaj: stackoverflow.com/questions/1264709/…
Jay Taylor,

Odpowiedzi:

201

Tworzenie i używanie strumieni we / wy tablicy bajtów jest następujące:

byte[] source = ...;
ByteArrayInputStream bis = new ByteArrayInputStream(source);
// read bytes from bis ...

ByteArrayOutputStream bos = new ByteArrayOutputStream();
// write bytes to bos ...
byte[] sink = bos.toByteArray();

Zakładając, że używasz sterownika JDBC, który implementuje standardowy interfejs JDBC Blob (nie wszyscy to robią), możesz również połączyć obiekt BLOB InputStreamlub OutputStreamdo obiektu blob za pomocą metod getBinaryStreami 1 , a także możesz bezpośrednio pobierać i ustawiać bajty.setBinaryStream

(Ogólnie rzecz biorąc, należy podjąć odpowiednie kroki, aby obsłużyć wszelkie wyjątki i zamknąć strumienie. Jednak zamykanie bisiw bospowyższym przykładzie jest niepotrzebne, ponieważ nie są one powiązane z żadnymi zasobami zewnętrznymi; np. Deskryptory plików, gniazda, połączenia z bazą danych).

1 - setBinaryStreamMetoda jest naprawdę getter. Domyśl.

Stephen C.
źródło
13

Zakładam, że masz na myśli, że „użycie” oznacza czytanie, ale to, co wyjaśnię dla przypadku odczytu, można w zasadzie odwrócić w przypadku zapisu.

więc otrzymujesz bajt []. może to oznaczać dowolny rodzaj danych, które mogą wymagać specjalnych typów konwersji (znakowych, zaszyfrowanych itp.). udawajmy, że chcesz zapisać te dane w pliku.

po pierwsze, możesz utworzyć ByteArrayInputStream, który jest w zasadzie mechanizmem dostarczania bajtów do czegoś w kolejności.

następnie możesz utworzyć FileOutputStream dla pliku, który chcesz utworzyć. istnieje wiele typów InputStreams i OutputStreams dla różnych źródeł danych i miejsc docelowych.

na koniec możesz napisać InputStream do OutputStream. w tym przypadku tablica bajtów zostanie wysłana w kolejności do FileOutputStream w celu zapisu. W tym celu polecam użycie IOUtils

byte[] bytes = ...;//
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
FileOutputStream out = new FileOutputStream(new File(...));
IOUtils.copy(in, out);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);

i na odwrót

FileInputStream in = new FileInputStream(new File(...));
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(in, out);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
byte[] bytes = out.toByteArray();

jeśli używasz powyższych fragmentów kodu, będziesz musiał obsłużyć wyjątki i zalecam wykonanie `` zamknięć '' w końcowym bloku.

pstanton
źródło
nie miałeś na myśli - ByteArrayOutputStream out = new ByteArrayOutputStream (); zamiast tego ByteArrayOutputStream out = new ByteArrayInputStream ();
Avihai Marchiano,
CloseQuietly powinno prawdopodobnie znajdować się w klauzuli końcowej.
JustinKSU
4

Nie ma konwersji między InputStream / OutputStream a bajtami, z którymi pracują. Są stworzone dla danych binarnych i po prostu czytają (lub zapisują) bajty jeden po drugim, tak jak jest.

Konwersja musi nastąpić, gdy chcesz przejść z bajtu na znak. Następnie musisz przekonwertować za pomocą zestawu znaków. Dzieje się tak, gdy tworzysz String lub Reader z bajtów, które są przeznaczone dla danych znakowych.

Thilo
źródło
1
output = new ByteArrayOutputStream();
...
input = new ByteArrayInputStream( output.toByteArray() )
DALDEI
źródło
0

Zdaję sobie sprawę, że moja odpowiedź jest spóźniona na to pytanie, ale myślę, że społeczność chciałaby nowszego podejścia do tej kwestii .

Sym-Sym
źródło
Bufory okrągłe nie rozwiązują problemu OP. W pytaniu, jak napisano, OP potrzebuje całej zawartości w tablicy jednobajtowej.
Stephen C
0
byte[] data = dbEntity.getBlobData();
response.getOutputStream().write();

Myślę, że jest to lepsze, ponieważ masz już istniejący OutputStream w obiekcie odpowiedzi. nie ma potrzeby tworzenia nowego OutputStream.

Stas Wishnevetsky
źródło