Saya berada pada tahap pengembangan, di mana saya memiliki dua modul dan dari satu saya mendapat output sebagai yang OutputStream
kedua, yang hanya menerima InputStream
. Apakah Anda tahu cara mengonversi OutputStream
ke InputStream
(bukan sebaliknya, maksud saya benar-benar seperti ini) sehingga saya dapat menghubungkan kedua bagian ini?
Terima kasih
java
inputstream
outputstream
Waypoint
sumber
sumber
new YourOutputStream(thePipedOutputStream)
dannew YourInputStream(thePipedInputStream)
yang mungkin bukan cara kerja aliran Anda. Jadi saya tidak berpikir ini solusinya.Jawaban:
An
OutputStream
adalah tempat Anda menulis data. Jika beberapa modul memaparkanOutputStream
, harapannya adalah ada sesuatu yang membaca di ujung lainnya.InputStream
Di lain pihak, sesuatu yang memperlihatkan suatu , menunjukkan bahwa Anda perlu mendengarkan aliran ini, dan akan ada data yang dapat Anda baca.Jadi dimungkinkan untuk menghubungkan
InputStream
keOutputStream
InputStream----read---> intermediateBytes[n] ----write----> OutputStream
Sebagai seseorang yang diceritakan, inilah yang dapat Anda lakukan dengan
copy()
metode dari IOUtils . Tidak masuk akal untuk pergi ke arah lain ... semoga ini masuk akalMEMPERBARUI:
Tentu saja semakin saya memikirkan hal ini, semakin saya bisa melihat bagaimana ini sebenarnya menjadi persyaratan. Saya tahu beberapa komentar menyebutkan
Piped
input / ouput stream, tetapi ada kemungkinan lain.Jika aliran output yang diekspos adalah
ByteArrayOutputStream
, maka Anda selalu bisa mendapatkan konten lengkap dengan memanggiltoByteArray()
metode. Kemudian Anda dapat membuat pembungkus aliran input dengan menggunakanByteArrayInputStream
sub-kelas. Keduanya adalah pseudo-stream, keduanya pada dasarnya hanya membungkus array byte. Menggunakan aliran seperti ini, oleh karena itu, secara teknis mungkin, tetapi bagi saya itu masih sangat aneh ...sumber
Tampaknya ada banyak tautan dan hal-hal lain semacam itu, tetapi tidak ada kode sebenarnya yang menggunakan pipa. Keuntungan menggunakan
java.io.PipedInputStream
danjava.io.PipedOutputStream
tidak ada konsumsi memori tambahan.ByteArrayOutputStream.toByteArray()
mengembalikan salinan buffer asli, sehingga itu berarti bahwa apa pun yang Anda miliki di memori, kini Anda memiliki dua salinannya. Kemudian menulis keInputStream
sarana berarti Anda sekarang memiliki tiga salinan data.Kode:
Kode ini mengasumsikan bahwa
originalByteArrayOutputStream
a adalahByteArrayOutputStream
karena biasanya merupakan satu-satunya aliran output yang dapat digunakan, kecuali jika Anda menulis ke file. Saya harap ini membantu! Hal yang hebat tentang ini adalah karena berada di utas terpisah, ia juga bekerja secara paralel, jadi apa pun yang mengonsumsi aliran input Anda akan mengalir keluar dari aliran output lama Anda juga. Itu menguntungkan karena buffer bisa tetap lebih kecil dan Anda akan memiliki latensi lebih sedikit dan penggunaan memori lebih sedikit.sumber
out
kein
konstruktor, jika tidak, Anda mungkin mendapatkan pengecualian pipa tertutupin
karena kondisi balapan (yang saya alami). Menggunakan Java 8 Lambdas:PipedInputStream in = new PipedInputStream(out); ((Runnable)() -> {originalOutputStream.writeTo(out);}).run(); return in;
originalOutputStream
yang seharusnya, tetapi tidak mengasumsikan bagaimana Anda mengontrol aliran Anda. Itu diserahkan kepada pengembang. Tidak ada dalam kode ini yang akan menyebabkan pengecualian pipa tertutup atau rusak.PipedInputStream
Javadocs: Sebuah pipa dikatakan rusak jika utas yang menyediakan byte data ke aliran keluaran pipa yang terhubung tidak lagi hidup. Jadi yang saya curigai adalah jika Anda menggunakan contoh di atas, utasnya selesai sebelumJax-RS
menggunakan aliran input. Pada saat yang sama, saya melihat MongoDB Javadocs.GridFSDBFile
memiliki aliran input, jadi mengapa tidak meneruskannya ke Jax-RS ?Karena input dan output stream hanya titik awal dan akhir, solusinya adalah menyimpan data sementara dalam array byte. Jadi, Anda harus membuat perantara
ByteArrayOutputStream
, dari mana Anda membuatbyte[]
yang digunakan sebagai input untuk yang baruByteArrayInputStream
.Semoga ini bisa membantu.
sumber
Anda akan membutuhkan kelas menengah yang akan buffer antara. Setiap kali
InputStream.read(byte[]...)
dipanggil, kelas buffering akan mengisi array byte yang dikirimkan dengan potongan berikutnya yang dilewatiOutputStream.write(byte[]...)
. Karena ukuran chunks mungkin tidak sama, kelas adaptor perlu menyimpan jumlah tertentu sampai cukup untuk mengisi buffer baca dan / atau dapat menyimpan buffer overflow.Artikel ini memiliki uraian bagus dari beberapa pendekatan berbeda untuk masalah ini:
http://blog.ostermiller.org/convert-java-outputstream-inputstream
sumber
sumber
toByteArray()
tubuh metode seperti inireturn Arrays.copyOf(buf, count);
yang mengembalikan array baru.The easystream perpustakaan open source memiliki dukungan langsung untuk mengkonversi OutputStream untuk InputStream: http://io-tools.sourceforge.net/easystream/tutorial/tutorial.html
Mereka juga mencantumkan opsi lain: http://io-tools.sourceforge.net/easystream/OutputStream_to_InputStream.html
sumber
Saya mengalami masalah yang sama dengan mengkonversi
ByteArrayOutputStream
keByteArrayInputStream
dan menyelesaikannya dengan menggunakan kelas turunan dariByteArrayOutputStream
yang mampu mengembalikanByteArrayInputStream
yang diinisialisasi dengan buffer internalByteArrayOutputStream
. Dengan cara ini tidak ada memori tambahan yang digunakan dan 'konversi' sangat cepat:Saya meletakkan barang-barang di github: https://github.com/nickrussler/ByteArrayInOutStream
sumber
Perpustakaan io-ekstra mungkin berguna. Misalnya jika Anda ingin gzip suatu
InputStream
penggunaanGZIPOutputStream
dan Anda ingin itu terjadi secara serempak (menggunakan ukuran buffer default 8192):Perhatikan bahwa perpustakaan memiliki cakupan uji unit 100% (untuk apa yang tentunya layak!) Dan ada di Maven Central. Ketergantungan Maven adalah:
Pastikan untuk memeriksa versi yang lebih baru.
sumber
Dari sudut pandang saya, java.io.PipedInputStream / java.io.PipedOutputStream adalah pilihan terbaik untuk dipertimbangkan. Dalam beberapa situasi Anda mungkin ingin menggunakan ByteArrayInputStream / ByteArrayOutputStream. Masalahnya adalah Anda perlu menduplikasi buffer untuk mengkonversi ByteArrayOutputStream ke ByteArrayInputStream. ByteArrayOutpuStream / ByteArrayInputStream juga terbatas hingga 2GB. Berikut ini adalah implementasi OutpuStream / InputStream yang saya tulis untuk mem-bypass keterbatasan ByteArrayOutputStream / ByteArrayInputStream (kode Scala, tetapi mudah dimengerti untuk java developpers):
Mudah digunakan, tidak ada duplikasi buffer, tidak ada batas memori 2GB
sumber
Jika Anda ingin membuat OutputStream dari InputStream ada satu masalah mendasar. Metode menulis ke blok OutputStream sampai selesai. Jadi hasilnya tersedia ketika metode penulisan selesai. Ini memiliki 2 konsekuensi:
Varian 1 dapat diimplementasikan menggunakan byte array atau diarsipkan. Varian 1 dapat diimplementasikan menggunakan pipies (baik secara langsung atau dengan abstraksi ekstra - mis. RingBuffer atau google lib dari komentar lain).
Memang dengan java standar tidak ada cara lain untuk menyelesaikan masalah. Setiap solusi adalah implementasi dari salah satunya.
Ada satu konsep yang disebut "kelanjutan" (lihat wikipedia untuk detail). Dalam hal ini pada dasarnya ini berarti:
Sementara beberapa bahasa memiliki konsep ini, untuk java Anda memerlukan "sihir". Misalnya "commons-javaflow" dari implementasi apache seperti untuk java. Kerugiannya adalah ini memerlukan beberapa modifikasi bytecode khusus pada waktu build. Jadi masuk akal untuk meletakkan semua barang di perpustakaan tambahan dengan skrip pembuatan kustom.
sumber
Posting lama tetapi mungkin membantu orang lain, Gunakan cara ini:
sumber
toString().getBytes()
stream * tidak akan mengembalikan konten stream.Meskipun Anda tidak dapat mengonversi OutputStream ke InputStream, java menyediakan cara menggunakan PipedOutputStream dan PipedInputStream sehingga Anda dapat memiliki data yang ditulis ke PipedOutputStream agar tersedia melalui PipedInputStream yang terkait.
Beberapa waktu yang lalu saya menghadapi situasi yang sama ketika berhadapan dengan perpustakaan pihak ketiga yang membutuhkan instance InputStream untuk diteruskan kepada mereka alih-alih instance OutputStream.
Cara saya memperbaiki masalah ini adalah dengan menggunakan PipedInputStream dan PipedOutputStream.
Omong-omong mereka sulit digunakan dan Anda harus menggunakan multithreading untuk mencapai apa yang Anda inginkan. Baru-baru ini saya menerbitkan implementasi di github yang dapat Anda gunakan.
Inilah tautannya . Anda dapat membaca wiki untuk memahami cara menggunakannya.
sumber