Kapan menggunakan deflate () dari deflateroutputstream?

Dec 23 2020

Saya mencoba mempelajari cara menggunakan deflateroutputstream sebagai sesuatu untuk menghabiskan waktu selama liburan musim dingin saya. Saya bingung karena saat melihat dokumentasinya,https://docs.oracle.com/javase/7/docs/api/java/util/zip/DeflaterOutputStream.html, dikatakan bahwa deflate () digunakan untuk menulis data yang dikompresi ke outputstream, sedangkan write () adalah untuk menulis data ke deflateroutputstream (outputstream yang dikompresi) untuk dikompresi.

Namun, saya sedang melihat kode sampel di internet, tetapi tidak ada yang menggunakan deflate () sama sekali. Semua kode yang saya lihat sejauh ini hanya menulis () ke deflateroutputstream tanpa memanggil deflate ().https://stackoverflow.com/a/13060441/12181863
https://www.programcreek.com/java-api-examples/?api=java.util.zip.DeflaterOutputStream

Saya perhatikan bahwa kode tersebut menempatkan fileoutputstream di dalam deflateroutputstream, tetapi bagaimana cara berinteraksi? Apakah secara otomatis memanggil deflate () untuk mengirim data terkompresi ke fileoutputstream ketika data ditulis ke deflateroutputstream?

Jawaban

3 rzwitserloot Dec 23 2020 at 21:21

Ini protected: Ini ditujukan untuk semua subclass yang menyubkelas aliran itu, dan Anda tidak membuat subkelasnya, sejauh yang Anda ketahui, ini adalah detail implementasi yang tidak dapat Anda sertakan dalam alasan Anda dan yang tidak dimaksudkan untuk Anda panggil.

Kecuali, tentu saja, Anda membuat subkelasnya.

Yang Anda bisa - ini semacam toolkit untuk membangun aliran kompresi berbasis LZ di atasnya. Itulah mengapa GZipOutputStream dan ZipOutputStream memperluasnya: Itu adalah wadah berbeda yang kurang lebih menggunakan teknologi kompresi yang sama. Dan mereka melakukan Invoke itu deflate. Kecuali jika Anda mengembangkan sistem kompresi berbasis LZ Anda sendiri atau mengimplementasikan pembaca untuk format kompresi berbasis non-zip, non-gz, non-deflater yang ada, ini tidak dimaksudkan untuk Anda.

Jenis arus keluaran ini disebut 'filterstreams': Mereka sendiri tidak mewakili sumber daya apa pun, mereka membungkusnya. Mereka dapat membungkus salah satu OutputStream(atau apa pun InputStream, konsep bekerja di 'kedua sisi' bisa dikatakan), dan memodifikasi byte saat transit.

var out = new DeflaterOutputStream(whatever)membuat aliran deflater baru yang akan memampatkan data apa pun yang Anda kirim ke sana (melalui out.write(stuff)), dan pada gilirannya akan mengambil data yang dikompresi dan mengirimkannya ke apa pun. Itu melakukan tugas:

  1. ambil byte (sesuai out.write), buffer sebanyak yang diperlukan untuk melakukan pekerjaan:
  2. ... untuk mengompresi data ini.
  3. Kemudian proses data yang dikompresi, setelah dikompresi, dengan mengirimkannya ke outputstream yang dibungkus ( whatever, dalam contoh ini), dengan memanggil writemetodenya.

Penggunaan dasarnya adalah:

  1. Buat sumber daya, seperti Files.newOutputStreamatau someSocket.getOutputStreamatau httpServletResponse.getOutputStream()atau System.outatau apa pun yang menghasilkan aliran - ini adalah konsep abstrak karena suatu alasan: Untuk membuat segala sesuatunya fleksibel.
  2. Bungkus sumber daya itu menjadi DeflaterOutputStream
  3. Tulis semua data Anda ke deflateroutputstream. Lupakan yang asli - Anda membuatnya sehingga Anda dapat meneruskannya ke DeflaterOutputStream, dan di sanalah interaksi Anda dengan aliran yang mendasarinya berakhir.
  4. Tutup aliran deflaterstream (yang pada akhirnya akan menutup aliran yang mendasarinya juga).