精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一文搞定Java NIO,以及各種奇葩流

開發(fā) 后端
本文為您講解了 Java I/O、NIO 以及其他一些流的基本概念、用法和區(qū)別。Java I/O 和 NIO 可以完成很多復(fù)雜的輸入輸出操作,包括文件操作、網(wǎng)絡(luò)編程、序列化等。其他流技術(shù)可以實(shí)現(xiàn)壓縮、讀寫字節(jié)數(shù)組等功能。在進(jìn)行開發(fā)時,根據(jù)具體需求選擇不同的流技術(shù)可以提高程序效率和開發(fā)效率。

大家好,我是哪吒。

很多朋友問我,如何才能學(xué)好IO流,對各種流的概念,云里霧里的,不求甚解。用到的時候,現(xiàn)百度,功能雖然實(shí)現(xiàn)了,但是為什么用這個?不知道。更別說效率問題了~

下次再遇到,再百度,“良性循環(huán)”。

今天,我就用一天的時間,整理一下關(guān)于Java I/O流的知識點(diǎn),分享給大家。

每一種IO流,都配有示例代碼,大家可以跟著敲一遍,找找感覺~

本篇文章介紹Java NIO以及其它的各種奇葩流。

Java NIO (New I/O) 是 Java 1.4 引入的,在 Java 7 中又進(jìn)行了一些增強(qiáng)。NIO 可以提高 I/O 操作的效率,它的核心是通道 (Channel) 和緩沖區(qū) (Buffer)。

一、Channel

Channel 是一種新的 I/O 抽象,它與傳統(tǒng)的 InputStream 和 OutputStream 不同,Channel 可以同時進(jìn)行讀和寫操作,而且可以對其進(jìn)行更細(xì)粒度的控制。Java NIO 中最基本的 Channel 包括:

1、FileChannel代碼示例

使用FileChannel從源文件中讀取內(nèi)容并將其寫入到目標(biāo)文件。

import java.io.FileInputStream;          // 引入 FileInputStream 類
import java.io.FileOutputStream;         // 引入 FileOutputStream 類
import java.nio.ByteBuffer;              // 引入 ByteBuffer 類
import java.nio.channels.FileChannel;    // 引入 FileChannel 類

public class FileChannelExample {
    public static void main(String[] args) {

        String sourceFile = "source.txt";
        String targetFile = "target.txt";

        try {
            // 使用 FileInputStream 和 FileOutputStream 打開源文件和目標(biāo)文件
            FileInputStream fileInputStream = new FileInputStream(sourceFile);
            FileOutputStream fileOutputStream = new FileOutputStream(targetFile);

            // 獲取 FileChannel 對象
            FileChannel sourceChannel = fileInputStream.getChannel();
            FileChannel targetChannel = fileOutputStream.getChannel();

            // 創(chuàng)建 ByteBuffer 對象
            ByteBuffer buffer = ByteBuffer.allocate(1024);

            // 從源文件中讀取內(nèi)容并將其寫入目標(biāo)文件
            while (sourceChannel.read(buffer) != -1) {
                buffer.flip();  // 準(zhǔn)備寫入(flip buffer)
                targetChannel.write(buffer);  // 向目標(biāo)文件寫入數(shù)據(jù)
                buffer.clear(); // 緩沖區(qū)清空(clear buffer)
            }

            // 關(guān)閉所有的 FileChannel、FileInputStream 和 FileOutputStream 對象
            sourceChannel.close();
            targetChannel.close();
            fileInputStream.close();
            fileOutputStream.close();

            // 打印成功信息
            System.out.println("文件復(fù)制成功!");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2、DatagramChannel代碼示例

用于 UDP 協(xié)議的數(shù)據(jù)讀寫操作。

使用DatagramChannel從一個端口讀取數(shù)據(jù)并將數(shù)據(jù)發(fā)送到另一個端口。

import java.io.IOException;                    // 引入 IOException 類
import java.net.InetSocketAddress;             // 引入 InetSocketAddress 類
import java.nio.ByteBuffer;                     // 引入 ByteBuffer 類
import java.nio.channels.DatagramChannel;       // 引入 DatagramChannel 類

public class DatagramChannelExample {
    public static void main(String[] args) {
        int receivePort = 8888;
        int sendPort = 9999;

        try {
            // 創(chuàng)建 DatagramChannel 對象
            DatagramChannel receiveChannel = DatagramChannel.open();

            // 綁定接收端口
            receiveChannel.socket().bind(new InetSocketAddress(receivePort));
            System.out.println("接收端口 " + receivePort + " 正在等待數(shù)據(jù)...");

            // 創(chuàng)建數(shù)據(jù)緩沖區(qū)對象
            ByteBuffer receiveBuffer = ByteBuffer.allocate(1024);

            // 從 receiveChannel 接收數(shù)據(jù)
            receiveChannel.receive(receiveBuffer);

            // 顯示收到的數(shù)據(jù)
            System.out.println("收到的數(shù)據(jù)是:" + new String(receiveBuffer.array()));

            // 關(guān)閉 receiveChannel 對象
            receiveChannel.close();

            // 創(chuàng)建 DatagramChannel 對象
            DatagramChannel sendChannel = DatagramChannel.open();

            // 創(chuàng)建數(shù)據(jù)緩沖區(qū)對象
            ByteBuffer sendBuffer = ByteBuffer.allocate(1024);

            // 向數(shù)據(jù)緩沖區(qū)寫入數(shù)據(jù)
            sendBuffer.clear();
            sendBuffer.put("Hello World".getBytes());
            sendBuffer.flip();

            // 發(fā)送數(shù)據(jù)到指定端口
            sendChannel.send(sendBuffer, new InetSocketAddress("localhost", sendPort));
            System.out.println("數(shù)據(jù)已發(fā)送到端口 " + sendPort);

            // 關(guān)閉 sendChannel 對象
            sendChannel.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3、SocketChannel 和 ServerSocketChannel代碼示例

用于 TCP 協(xié)議的數(shù)據(jù)讀寫操作。

下面是一個簡單的示例,演示如何使用 SocketChannel 和 ServerSocketChannel 進(jìn)行基本的 TCP 數(shù)據(jù)讀寫操作。

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class TCPExample {
    public static void main(String[] args) throws Exception {
        // 創(chuàng)建 ServerSocketChannel 并綁定端口
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(8888));
        serverSocketChannel.configureBlocking(false);

        // 創(chuàng)建一個 ByteBuffer 用于接收數(shù)據(jù)
        ByteBuffer buf = ByteBuffer.allocate(1024);

        // 等待客戶端連接
        while (true) {
            SocketChannel socketChannel = serverSocketChannel.accept();
            if (socketChannel != null) {
                // 客戶端已連接,從 SocketChannel 中讀取數(shù)據(jù)
                int bytesRead = socketChannel.read(buf);
                while (bytesRead != -1) {
                    // 處理讀取到的數(shù)據(jù)
                    System.out.println(new String(buf.array(), 0, bytesRead));
                    
                    // 清空 ByteBuffer,進(jìn)行下一次讀取
                    buf.clear();
                    bytesRead = socketChannel.read(buf);
                }
            }
        }
    }
}

示例代碼說明:

  • 創(chuàng)建一個 ServerSocketChannel 并綁定到本地端口 8888,然后將其設(shè)置為非阻塞模式。
  • 創(chuàng)建一個 ByteBuffer 用于接收數(shù)據(jù)。
  • 進(jìn)入一個死循環(huán),不斷等待客戶端連接。
  • 當(dāng)客戶端連接時,從 SocketChannel 中讀取數(shù)據(jù),并將讀取到的數(shù)據(jù)打印到控制臺。
  • 清空 ByteBuffer,進(jìn)行下一次讀取。

需要注意的點(diǎn):

  • 在代碼中每次讀取結(jié)束都需要清空 ByteBuffer,否則其 position 屬性不會自動歸零,可能導(dǎo)致數(shù)據(jù)讀取不正確。
  • 由于使用非阻塞模式,如果調(diào)用了 accept() 方法但沒有立即接收到客戶端連接,該方法會返回 null,需要繼續(xù)循環(huán)等待。
  • 本代碼只演示了從客戶端讀取數(shù)據(jù)的部分,如果需要向客戶端發(fā)送數(shù)據(jù)需要調(diào)用SocketChannel.write()方法

如果想要向客戶端發(fā)送數(shù)據(jù),可以使用以下代碼:

// 創(chuàng)建一個 ByteBuffer 用于發(fā)送數(shù)據(jù)
ByteBuffer buf = ByteBuffer.wrap("Hello, world!".getBytes());

// 向客戶端發(fā)送數(shù)據(jù)
socketChannel.write(buf);

二、Buffer

Buffer 是一個對象,它包含一些要寫入或要讀出的數(shù)據(jù)。在 NIO 中,Buffer 可以被看作為一個字節(jié)數(shù)組,但是它的讀取和寫入操作比直接的字節(jié)數(shù)組更加高效。NIO 中最常用的 Buffer 類型包括:

1、ByteBuffer示例代碼

字節(jié)緩沖區(qū),最常用的緩沖區(qū)類型,用于對字節(jié)數(shù)據(jù)的讀寫操作。

import java.nio.ByteBuffer;

public class ByteBufferExample {
  public static void main(String[] args) {
    // 創(chuàng)建一個新的字節(jié)緩沖區(qū),初始容量為10個字節(jié)
    ByteBuffer buffer = ByteBuffer.allocate(10);
    
    // 向緩沖區(qū)中寫入4個字節(jié)
    buffer.put((byte) 1);
    buffer.put((byte) 2);
    buffer.put((byte) 3);
    buffer.put((byte) 4);
    
    // 輸出緩沖區(qū)中的內(nèi)容
    buffer.flip(); // 將緩沖區(qū)切換成讀模式
    System.out.println(buffer.get()); // 輸出1
    System.out.println(buffer.get()); // 輸出2
    System.out.println(buffer.get()); // 輸出3
    System.out.println(buffer.get()); // 輸出4
    
    // 將緩沖區(qū)清空并重新寫入數(shù)據(jù)
    buffer.clear();
    buffer.put((byte) 5);
    buffer.put((byte) 6);
    buffer.put((byte) 7);
    buffer.put((byte) 8);
    
    // 輸出緩沖區(qū)中的內(nèi)容,方法同上
    buffer.flip();
    System.out.println(buffer.get()); // 輸出5
    System.out.println(buffer.get()); // 輸出6
    System.out.println(buffer.get()); // 輸出7
    System.out.println(buffer.get()); // 輸出8
  }
}

示例代碼說明:

  • 在上面的示例中,我們使用ByteBuffer類的allocate()方法創(chuàng)建了一個新的字節(jié)緩沖區(qū),然后向緩沖區(qū)中寫入4個字節(jié)的數(shù)據(jù)。
  • 接著,我們通過調(diào)用flip()方法將緩沖區(qū)切換成讀模式,并使用get()方法讀取緩沖區(qū)中的數(shù)據(jù),并按順序輸出每個字節(jié)。
  • 最后,我們清空緩沖區(qū)并重新寫入數(shù)據(jù),再次將緩沖區(qū)切換成讀模式,并使用get()方法讀取緩沖區(qū)中的數(shù)據(jù)。

2、CharBuffer示例代碼

字符緩沖區(qū),用于對字符數(shù)據(jù)的讀寫操作。

import java.nio.CharBuffer;

public class CharBufferExample {
    public static void main(String[] args) {
        // 創(chuàng)建一個新的字符緩沖區(qū),初始容量為10個字符
        CharBuffer buffer = CharBuffer.allocate(10);
        
        // 向緩沖區(qū)中寫入4個字符
        buffer.put('a');
        buffer.put('b');
        buffer.put('c');
        buffer.put('d');
        
        // 輸出緩沖區(qū)中的內(nèi)容
        buffer.flip(); // 將緩沖區(qū)切換成讀模式
        System.out.println(buffer.get()); // 輸出a
        System.out.println(buffer.get()); // 輸出b
        System.out.println(buffer.get()); // 輸出c
        System.out.println(buffer.get()); // 輸出d
        
        // 將緩沖區(qū)清空并重新寫入數(shù)據(jù)
        buffer.clear();
        buffer.put('e');
        buffer.put('f');
        buffer.put('g');
        buffer.put('h');
        
        // 輸出緩沖區(qū)中的內(nèi)容,方法同上
        buffer.flip();
        System.out.println(buffer.get()); // 輸出e
        System.out.println(buffer.get()); // 輸出f
        System.out.println(buffer.get()); // 輸出g
        System.out.println(buffer.get()); // 輸出h
    }
}

示例代碼說明:

  • 在上面的示例中,我們使用CharBuffer類的allocate()方法創(chuàng)建了一個新的字符緩沖區(qū),然后向緩沖區(qū)中寫入4個字符的數(shù)據(jù)。
  • 接著,我們通過調(diào)用flip()方法將緩沖區(qū)切換成讀模式,并使用get()方法讀取緩沖區(qū)中的數(shù)據(jù),并按順序輸出每個字符。
  • 最后,我們清空緩沖區(qū)并重新寫入數(shù)據(jù),再次將緩沖區(qū)切換成讀模式,并使用get()方法讀取緩沖區(qū)中的數(shù)據(jù)。

3、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer 等示例代碼

import java.nio.*;

public class BasicBufferExample {
    public static void main(String[] args) {
        // 創(chuàng)建各種基本數(shù)據(jù)類型的緩沖區(qū),初始容量為10
        ShortBuffer shortBuf = ShortBuffer.allocate(10);
        IntBuffer intBuf = IntBuffer.allocate(10);
        LongBuffer longBuf = LongBuffer.allocate(10);
        FloatBuffer floatBuf = FloatBuffer.allocate(10);
        DoubleBuffer doubleBuf = DoubleBuffer.allocate(10);
        
        // 向緩沖區(qū)中寫入數(shù)據(jù)
        shortBuf.put((short) 1);
        intBuf.put(2);
        longBuf.put(3L);
        floatBuf.put(4.0f);
        doubleBuf.put(5.0);
        
        // 反轉(zhuǎn)緩沖區(qū),切換到讀模式
        shortBuf.flip();
        intBuf.flip();
        longBuf.flip();
        floatBuf.flip();
        doubleBuf.flip();
        
        // 讀取緩沖區(qū)中的數(shù)據(jù)
        System.out.println(shortBuf.get()); // 輸出1
        System.out.println(intBuf.get()); // 輸出2
        System.out.println(longBuf.get()); // 輸出3
        System.out.println(floatBuf.get()); // 輸出4.0
        System.out.println(doubleBuf.get()); // 輸出5.0
    }
}

示例代碼說明:

  • 在上面的示例中,我們分別創(chuàng)建了ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer等基本數(shù)據(jù)類型的緩沖區(qū)。
  • 接著,我們向這些緩沖區(qū)中寫入了對應(yīng)數(shù)據(jù)類型的數(shù)據(jù)。
  • 然后我們通過調(diào)用flip()方法,將緩沖區(qū)切換成讀模式,并通過get()方法讀取緩沖區(qū)中的數(shù)據(jù),并按順序輸出每一個數(shù)據(jù)類型的內(nèi)容。

三、Selector

Selector 是 Java NIO 類庫中的一個重要組件,它用于監(jiān)聽多個 Channel 的事件。在一個線程中,通過 Selector 可以監(jiān)聽多個 Channel 的 IO 事件,并實(shí)現(xiàn)了基于事件響應(yīng)的架構(gòu)。Selector 可以讓單個線程處理多個 Channel,因此它可以提高多路復(fù)用的效率。

1、Selector讓單線程處理多個Channel的代碼示例

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

public class SelectorExample {
    public static void main(String[] args) throws IOException {
        // 創(chuàng)建一個ServerSocketChannel,監(jiān)聽本地端口
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress("localhost", 8080));
        serverSocketChannel.configureBlocking(false);
        
        // 創(chuàng)建一個Selector,并將serverSocketChannel注冊到Selector上
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        System.out.println("Server started on port 8080");

        while (true) {
            // 如果沒有任何事件發(fā)生,則阻塞等待
            selector.select();

            // 處理事件
            Set<SelectionKey> selectedKeys = selector.selectedKeys();
            Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
            while (keyIterator.hasNext()) {
                SelectionKey key = keyIterator.next();

                if (key.isAcceptable()) {
                    // 處理新的連接請求
                    ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
                    SocketChannel clientChannel = serverChannel.accept();
                    clientChannel.configureBlocking(false);
                    System.out.println("Accepted connection from " + clientChannel.getRemoteAddress());
                    clientChannel.register(selector, SelectionKey.OP_READ);

                } else if (key.isReadable()) {
                    // 處理讀事件
                    SocketChannel clientChannel = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int bytesRead = clientChannel.read(buffer);
                    String message = new String(buffer.array(), 0, bytesRead);
                    System.out.println("Received message from " + clientChannel.getRemoteAddress() + ": " + message);

                    // 回寫數(shù)據(jù)
                    ByteBuffer outputBuffer = ByteBuffer.wrap(("Echo: " + message).getBytes());
                    clientChannel.write(outputBuffer);
                }

                // 從待處理事件集合中移除當(dāng)前事件
                keyIterator.remove();
            }
        }
    }
}

2、示例代碼說明

  • 使用ServerSocketChannel監(jiān)聽本地8080端口,并將ServerSocketChannel注冊到Selector上。
  • 在while循環(huán)中,我們通過調(diào)用select()方法等待事件發(fā)生,如果有事件發(fā)生,則從Selector中獲取待處理事件集合,然后遍歷事件集合,處理每個事件。
  • 如果當(dāng)前事件是新的連接請求,則接受該連接,并將對應(yīng)的SocketChannel注冊到Selector上,使用OP_READ模式表示可以讀取數(shù)據(jù)。
  • 如果當(dāng)前事件是可讀的,則讀取SocketChannel中的數(shù)據(jù)并進(jìn)行回寫,回寫時使用ByteBuffer包裝需要回寫的數(shù)據(jù),并將其寫入到SocketChannel中。
  • 最后,我們從待處理事件集合中移除當(dāng)前事件。

四、ZipInputStream 和 ZipOutputStream

ZipInputStream 和 ZipOutputStream 可以用于處理 ZIP 文件格式,ZipInputStream 可以從 ZIP 文件中讀取數(shù)據(jù),ZipOutputStream 可以向 ZIP 文件中寫入數(shù)據(jù)。

1、ZipInputStream示例代碼

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipExample {
    public static void main(String[] args) throws IOException {
        // 輸入文件路徑和輸出壓縮文件路徑
        String inputFile = "/path/to/input/file";
        String outputFile = "/path/to/output/file.zip";

        // 創(chuàng)建ZipOutputStream,并設(shè)置壓縮級別
        ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(outputFile));
        zipOutputStream.setLevel(9);

        // 讀取需要壓縮的文件到文件輸入流
        FileInputStream fileInputStream = new FileInputStream(inputFile);
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

        // 設(shè)置壓縮文件內(nèi)部的名稱
        ZipEntry zipEntry = new ZipEntry(inputFile);
        zipOutputStream.putNextEntry(zipEntry);

        // 寫入壓縮文件
        byte[] buf = new byte[1024];
        int len;
        while ((len = bufferedInputStream.read(buf)) > 0) {
            zipOutputStream.write(buf, 0, len);
        }

        bufferedInputStream.close();
        zipOutputStream.closeEntry();
        zipOutputStream.close();

        System.out.println("File compressed successfully");
    }
}

示例代碼說明:

  • 首先,我們創(chuàng)建ZipOutputStream并設(shè)置壓縮級別。
  • 接著,我們創(chuàng)建輸入文件的FileInputStream,并使用BufferedInputStream包裝它。
  • 我們接著設(shè)置壓縮文件內(nèi)部的名稱,并使用zipOutputStream.putNextEntry()方法將其寫入ZipOutputStream中。
  • 最后,我們從緩沖區(qū)讀取文件數(shù)據(jù)并將其寫入ZipOutputStream中。最后關(guān)閉輸入流和ZipOutputStream。

2、ZipOutputStream示例代碼

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class UnzipExample {
    public static void main(String[] args) throws IOException {
        // 輸入壓縮文件路徑和輸出文件路徑
        String inputFile = "/path/to/input/file.zip";
        String outputFile = "/path/to/output/file";

        // 創(chuàng)建ZipInputStream
        ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(inputFile));

        // 循環(huán)讀取壓縮文件中的條目
        ZipEntry zipEntry = zipInputStream.getNextEntry();
        while (zipEntry != null) {
            // 如果是目錄,則創(chuàng)建空目錄
            if (zipEntry.isDirectory()) {
                new File(outputFile + File.separator + zipEntry.getName()).mkdirs();

            } else { // 如果是文件,則輸出文件
                FileOutputStream fileOutputStream = new FileOutputStream(outputFile + File.separator
                        + zipEntry.getName());
                byte[] buf = new byte[1024];
                int len;
                while ((len = zipInputStream.read(buf)) > 0) {
                    fileOutputStream.write(buf, 0, len);
                }
                fileOutputStream.close();
            }

            zipInputStream.closeEntry();
            zipEntry = zipInputStream.getNextEntry();
        }

        zipInputStream.close();

        System.out.println("File uncompressed successfully");
    }
}

示例代碼說明:

  • 使用ZipInputStream從指定輸入文件中解壓文件到指定的輸出文件夾中。
  • 我們創(chuàng)建ZipInputStream,然后循環(huán)讀取壓縮文件中的條目。如果當(dāng)前條目是目錄,則創(chuàng)建空目錄,并使用mkdirs()方法創(chuàng)建目錄。如果當(dāng)前條目是文件,則使用FileOutputStream將文件寫入到指定的輸出文件中。
  • 最后關(guān)閉當(dāng)前ZipEntry,并通過getNextEntry()方法獲取ZipInputStream中的下一個條目。

五、GZIPInputStream 和 GZIPOutputStream

GZIPInputStream 和 GZIPOutputStream 可以用于進(jìn)行 GZIP 壓縮,GZIPInputStream 可以從壓縮文件中讀取數(shù)據(jù),GZIPOutputStream 可以將數(shù)據(jù)寫入壓縮文件中。

1、GZIPInputStream代碼示例

import java.io.*;
import java.util.zip.GZIPOutputStream;

public class GzipExample {
    public static void main(String[] args) throws IOException {
        // 輸入文件路徑和輸出壓縮文件路徑
        String inputFile = "/path/to/input/file";
        String outputFile = "/path/to/output/file.gz";

        // 創(chuàng)建GZIPOutputStream,并設(shè)置壓縮級別
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new FileOutputStream(outputFile));
        gzipOutputStream.setLevel(9);

        // 讀取需要壓縮的文件到文件輸入流
        FileInputStream fileInputStream = new FileInputStream(inputFile);
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

        // 寫入壓縮文件
        byte[] buf = new byte[1024];
        int len;
        while ((len = bufferedInputStream.read(buf)) > 0) {
            gzipOutputStream.write(buf, 0, len);
        }

        bufferedInputStream.close();
        gzipOutputStream.close();

        System.out.println("File compressed successfully");
    }
}

示例代碼說明:

  • 使用GZIPOutputStream將指定的輸入文件壓縮成輸出文件。
  • 首先,創(chuàng)建GZIPOutputStream并設(shè)置壓縮級別。
  • 接著,創(chuàng)建輸入文件的FileInputStream,并使用BufferedInputStream包裝它。
  • 接著從緩沖區(qū)讀取文件數(shù)據(jù)并將其寫入GZIPOutputStream中。最后關(guān)閉輸入流和GZIPOutputStream。

2、GZIPOutputStream代碼示例

import java.io.*;
import java.util.zip.GZIPInputStream;

public class GunzipExample {
    public static void main(String[] args) throws IOException {
        // 輸入壓縮文件路徑和輸出文件路徑
        String inputFile = "/path/to/input/file.gz";
        String outputFile = "/path/to/output/file";

        // 創(chuàng)建GZIPInputStream
        GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(inputFile));

        // 輸出文件
        FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
        byte[] buf = new byte[1024];
        int len;
        while ((len = gzipInputStream.read(buf)) > 0) {
            fileOutputStream.write(buf, 0, len);
        }

        gzipInputStream.close();
        fileOutputStream.close();

        System.out.println("File uncompressed successfully");
    }
}

示例代碼說明:

  • 使用GZIPInputStream從指定輸入文件中解壓文件到指定的輸出文件中。
  • 首先,我們創(chuàng)建GZIPInputStream,然后從緩沖區(qū)讀取文件數(shù)據(jù)并將其寫入到指定的輸出文件中。
  • 最后,我們關(guān)閉輸入流和輸出流。

六、ByteArrayInputStream 和 ByteArrayOutputStream

ByteArrayInputStream 和 ByteArrayOutputStream 分別是 ByteArrayInputStream 和 ByteArrayOutputStream 類的子類,它們可以用于對字節(jié)數(shù)組進(jìn)行讀寫操作。

1、ByteArrayInputStream 代碼示例

import java.io.ByteArrayInputStream;

import java.io.ByteArrayInputStream;
import java.io.IOException;

public class ByteArrayInputStreamExample {
    public static void main(String[] args) throws IOException {
        // 用字符串初始化一個字節(jié)數(shù)組,作為輸入數(shù)據(jù)源
        String input = "Hello, world!";
        byte[] inputBytes = input.getBytes();

        // 創(chuàng)建一個ByteArrayInputStream,使用輸入數(shù)據(jù)源
        ByteArrayInputStream inputStream = new ByteArrayInputStream(inputBytes);

        // 讀取并輸出輸入流中的數(shù)據(jù)
        byte[] buf = new byte[1024];
        int len;
        while ((len = inputStream.read(buf)) != -1) {
            System.out.println(new String(buf, 0, len));
        }

        // 關(guān)閉輸入流
        inputStream.close();
    }
}

示例代碼說明:

  • 使用“Hello, world!”字符串創(chuàng)建了一個字節(jié)數(shù)組作為輸入數(shù)據(jù)源,并使用ByteArrayInputStream將其包裝成輸入流。
  • 使用一個循環(huán)從輸入流中讀取數(shù)據(jù),并使用new String()方法將其轉(zhuǎn)換成字符串并輸出到控制臺。
  • 最后,關(guān)閉輸入流。

2、ByteArrayOutputStream代碼示例

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class ByteArrayOutputStreamExample {
    public static void main(String[] args) {
        String input = "Hello World!";
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] output;

        try {
            outputStream.write(input.getBytes());
            output = outputStream.toByteArray();
            System.out.println(new String(output));
        } catch (IOException e) {
            System.out.println("Error: " + e.getMessage());
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                System.out.println("Error: " + e.getMessage());
            }
        }
    }
}

示例代碼說明:

  • 在這個例子中,創(chuàng)建了一個ByteArrayOutputStream對象 outputStream,并向其寫入一個字符串"Hello World!"。然后,我們使用toByteArray()方法將結(jié)果轉(zhuǎn)換為一個字節(jié)數(shù)組,并打印出來。
  • 注意:在使用ByteArrayOutputStream時,要確保在不再需要它時關(guān)閉它以確保所有的字節(jié)都被刷新到輸出流中。

七、總結(jié)

本文為您講解了 Java I/O、NIO 以及其他一些流的基本概念、用法和區(qū)別。Java I/O 和 NIO 可以完成很多復(fù)雜的輸入輸出操作,包括文件操作、網(wǎng)絡(luò)編程、序列化等。其他流技術(shù)可以實(shí)現(xiàn)壓縮、讀寫字節(jié)數(shù)組等功能。在進(jìn)行開發(fā)時,根據(jù)具體需求選擇不同的流技術(shù)可以提高程序效率和開發(fā)效率。

本文轉(zhuǎn)載自微信公眾號「哪吒編程」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系哪吒編程公眾號。

責(zé)任編輯:姜華 來源: 哪吒編程
相關(guān)推薦

2019-09-23 10:51:14

JavaJava虛擬機(jī)Linux

2024-01-09 08:24:47

JMM核心線程

2021-08-13 05:50:01

ContainerdDockerKubernetes

2021-03-28 18:40:02

LinuxWindowsJava

2021-10-25 16:01:01

Linux設(shè)備樹字符串

2022-08-17 18:25:37

Java分布式搜索引擎

2025-08-08 01:11:00

React組件通信

2021-08-31 07:02:20

Diff算法DOM

2021-10-06 20:23:08

Linux共享內(nèi)存

2020-10-29 08:55:04

微服務(wù)

2025-05-30 02:21:00

Dify人工智能LLMOps

2023-07-26 08:22:17

JavaIO流

2022-04-15 08:03:41

SaaS應(yīng)用管理市場

2021-04-19 17:32:34

Java內(nèi)存模型

2021-08-31 07:02:34

數(shù)據(jù)響應(yīng)Vue偵測數(shù)據(jù)變化

2023-04-18 08:45:28

MongoDB部署模式

2021-04-02 06:17:10

大數(shù)加減乘除數(shù)據(jù)結(jié)構(gòu)算法

2025-04-07 08:20:00

ORMPython代碼

2020-11-30 12:32:40

PyTorch語義分割python

2025-09-02 09:02:30

LinuxWindows雙系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

日本a在线观看| 久久久久久蜜桃一区二区| 蜜桃av噜噜一区二区三区麻豆 | 欧美日本国产精品| 无码人妻丰满熟妇区bbbbxxxx| 日韩黄色大片| 亚洲成人av片| 国产福利在线免费| 国产激情在线播放| 国产精品乱码一区二三区小蝌蚪| 99国精产品一二二线| 国产中文字幕视频| 在线观看日韩| 亚洲天堂男人天堂女人天堂| 亚洲成人激情小说| 视频一区在线免费看| 亚洲精品视频在线观看网站| 欧美一区二区三区四区在线观看地址 | 天天干天天操av| 久久er精品视频| 欧美在线日韩在线| 激情五月少妇a| 欧美日韩有码| 日韩精品福利网站| 性一交一黄一片| 国产第一亚洲| 91久久国产最好的精华液| 久久久国内精品| 免费高清完整在线观看| 国产在线视频二区| 秋霞蜜臀av久久电影网免费| 欧美一区二区三区爱爱| 成人性做爰aaa片免费看不忠| 国产第一页在线| 亚洲青青青在线视频| 日本一区二区视频| 日韩大胆视频| 91在线观看地址| 91蜜桃网站免费观看| 亚洲一级在线播放| 老司机久久99久久精品播放免费| 久久久免费精品| 欧美另类视频在线观看| 久久精品播放| 色偷偷av一区二区三区| 亚洲天堂最新地址| 久久av影视| 亚洲另类激情图| 人人妻人人澡人人爽人人精品 | 春色成人在线视频| 国产免费叼嘿网站免费| 久久精品国产99| 国产精品免费视频久久久| 嫩草影院一区二区三区| 首页欧美精品中文字幕| 日本道色综合久久影院| 日韩一级片免费视频| 伊人影院在线观看视频| 欧美视频免费看| 欧美日韩视频在线第一区 | 人人精品人人爱| 国产精品久久久久久久9999| 亚洲男人天堂网址| 蜜臀av亚洲一区中文字幕| 国产精品美女久久| 无码人妻一区二区三区免费| 日韩福利电影在线| 国产精品免费网站| 国产深喉视频一区二区| 大陆成人av片| 久久国产主播精品| 成人77777| 中文字幕一区二区三区不卡在线 | 国产精品伦子伦| 欧美电影在线观看免费| 亚洲性猛交xxxxwww| 国产人与禽zoz0性伦| 99re6这里只有精品| 欧美精品在线观看| 日本免费观看视| 日本特黄久久久高潮| 国产日韩欧美在线看| 国产suv一区二区| 99亚偷拍自图区亚洲| 欧洲精品在线一区| 黄色网页在线观看| 五月天亚洲婷婷| 午夜免费高清视频| 综合成人在线| 伊人av综合网| 欧美激情精品久久| 久久资源在线| 91香蕉电影院| 久久99久久99精品免费看小说| av网站在线免费看| 国产福利视频一区二区三区| 精品国产aⅴ麻豆| 一级毛片视频在线观看| 亚洲成人精品影院| 日韩不卡一二三| youjizzjizz亚洲| 伊人伊成久久人综合网小说| 国产性生活网站| 日韩av中文字幕一区二区| 999国内精品视频在线| 免费黄色片在线观看| 成人视屏在线观看| 日本亚洲不卡| 亚洲国产三级网| 日本免费网站视频| 亚洲永久免费精品| 麻豆精品视频在线观看| 欧美视频一区二| 9191在线视频| 欧美精品羞羞答答| 性亚洲最疯狂xxxx高清| 97超视频在线观看| 久久精品人人做| 成人网站免费观看入口| 欧美一区二区三区婷婷| 日韩精品视频在线播放| 福利所第一导航| 欧美aa在线视频| 久久久久久国产精品免费免费| 激情视频在线观看| 欧美中文字幕一二三区视频| 国产精品扒开腿做爽爽爽a片唱戏| 久久精品高清| 国产精品福利小视频| 香蕉av一区二区三区| 艳妇臀荡乳欲伦亚洲一区| 色戒在线免费观看| 欧美精选一区二区三区| 97香蕉久久超级碰碰高清版| 精品国产av一区二区| 亚洲日本乱码在线观看| 亚洲欧美日韩精品一区| 欧美裸体在线版观看完整版| 欧美中文在线视频| 亚洲AV第二区国产精品| 亚洲mv在线观看| 26uuu国产| 欧美~级网站不卡| 亚洲一区中文字幕| 黄色网页在线播放| 欧美一区二区视频观看视频| 免费在线观看a级片| 精品亚洲欧美一区| 91免费网站视频| 懂色av色香蕉一区二区蜜桃| 日韩在线视频播放| 亚洲字幕av一区二区三区四区| 欧美国产成人精品| 校园春色 亚洲色图| 成人3d精品动漫精品一二三| 久久久久午夜电影| 日韩在线视频二区| 国产免费叼嘿网站免费| 亚洲欧洲综合另类| 亚洲欧美日韩中文字幕在线观看| 一区二区三区四区在线观看国产日韩| 91在线视频成人| 羞羞网站在线免费观看| 亚洲成人精品在线| 国内自拍视频在线播放| 久久久久久久精| 9久久婷婷国产综合精品性色| 精品国产精品国产偷麻豆| 国产精品久久久久久久久久三级| 日本免费在线观看| 日韩午夜在线影院| 日韩 欧美 亚洲| 久久精品亚洲精品国产欧美| 日韩精品你懂的| 综合国产精品| 久久香蕉综合色| 久久er热在这里只有精品66| 欧美成人一区二区三区电影| 噜噜噜久久,亚洲精品国产品| 色呦呦一区二区三区| 欧美性猛交xxxx乱大交少妇| 国产精品一二三四区| 鲁一鲁一鲁一鲁一色| 国产一区三区在线播放| 91欧美日韩一区| 国产精品蜜芽在线观看| 一区二区三区天堂av| 99热在线只有精品| 精品国产乱码久久久久久婷婷| 精品无码人妻一区二区免费蜜桃| 久久97超碰色| 日韩中文字幕三区| 欧美激情国产在线| 久久久99爱| 香蕉成人在线| 欧美影院久久久| 成人在线网址| 亚洲欧美中文日韩v在线观看| 国产女人爽到高潮a毛片| 欧美日韩国产色| 精品亚洲乱码一区二区| www.av精品| 欧美黑人性生活视频| 麻豆视频在线免费看| 91麻豆国产福利在线观看| 制服丝袜中文字幕第一页 | 99久久久国产精品免费调教网站| 欧美精品在线免费| 大胆av不用播放器在线播放 | 午夜久久福利影院| sm捆绑调教视频| 久久久久久久久久久99999| ass极品水嫩小美女ass| 日韩电影在线看| 欧美久久久久久久久久久久久 | 成人av综合一区| 亚洲欧美在线精品| 亚洲自啪免费| 老子影院午夜伦不卡大全| 91亚洲人成网污www| 免费国产一区二区| 免费福利视频一区| 99中文视频在线| 91视频亚洲| 国产精品视频在线观看| 男人av在线播放| 欧美疯狂做受xxxx高潮| 国产一二区在线| 最新国产成人av网站网址麻豆| 亚洲欧美综合在线观看| 精品国产sm最大网站免费看| 国产高清在线观看视频| 欧美裸体bbwbbwbbw| 国产精品传媒在线观看| 欧美视频中文字幕在线| 日韩欧美大片在线观看| 一区二区成人在线视频| 欧美精品一区二区蜜桃| 亚洲欧美一区二区三区极速播放| 亚洲一级片在线播放| 久久精品欧美日韩| 国产ts在线播放| 国产亚洲短视频| 91精品人妻一区二区三区| 91视频你懂的| 干b视频在线观看| 国产亚洲视频系列| 精品人伦一区二区三电影| 2017欧美狠狠色| 久久av无码精品人妻系列试探| 91蜜桃网址入口| 美女被到爽高潮视频| 国产三级三级三级精品8ⅰ区| www.中文字幕av| 国产欧美日韩在线视频| 欧美巨胸大乳hitomi| 国产精品拍天天在线| 天堂网av2018| 亚洲三级在线看| 老妇女50岁三级| 香蕉影视欧美成人| 国产精品男女视频| 欧美亚洲丝袜传媒另类| 亚洲手机在线观看| 91精品综合久久久久久| 亚洲精品字幕在线| 国产婷婷色综合av蜜臀av| 可以在线观看的av| 中文字幕日韩视频| av大全在线| 97精品在线视频| 国产另类xxxxhd高清| 国产在线日韩在线| caoporn成人| 欧美成人第一区| 日韩午夜电影网| 欧美黄网在线观看| 国产日本精品| 亚洲娇小娇小娇小| 高清视频一区二区| 国产精久久一区二区三区| 中文字幕一区二区三区不卡在线| 久久久久黄色片| 欧美日韩一区二区免费视频| 久久这里只有精品9| 欧美一区二区三区影视| 亚州av在线播放| 北条麻妃久久精品| 亚洲高清视频在线观看| 精品久久久久中文字幕小说 | 欧美精品观看| 欧美日韩亚洲一二三| 国产福利一区二区三区在线视频| 欧美 日本 国产| 亚洲欧洲精品天堂一级| 日本网站免费观看| 欧美日韩中字一区| 日本韩国免费观看| 日韩中文字幕国产精品| 国产社区精品视频| 国产欧美一区二区三区在线看| 99国产精品久久一区二区三区| 欧美日韩电影一区二区| 亚洲欧美亚洲| 国产自偷自偷免费一区| 丁香婷婷深情五月亚洲| 日本一卡二卡在线播放| 亚洲午夜久久久久久久久电影网 | 一二三区精品福利视频| 亚洲另类在线观看| 日韩欧美一区在线| 成人资源www网在线最新版| 欧美黑人性视频| 久久精品xxxxx| 欧美男人的天堂| 亚洲国产免费看| 成人免费播放视频| 国产精品久久久久久久第一福利| 亚洲天堂一区在线观看| 精品少妇一区二区三区在线播放| 幼a在线观看| 国产91色在线|免| 卡通动漫国产精品| www.激情网| 国产呦精品一区二区三区网站| 蜜桃av乱码一区二区三区| 精品国产91久久久久久| 亚洲狼人综合网| 欧美成人免费播放| 欧美男男gaygay1069| 欧美日韩国产高清视频| 日韩一级在线| 国产污在线观看| 依依成人精品视频| 国产福利视频导航| 久久艳片www.17c.com | 亚洲经典在线看| 久久久久亚洲av无码网站| 亚洲免费观看在线观看| 91美女精品网站| 中文字幕欧美日韩| 日本h片久久| 一个色的综合| 黄色影院在线播放| 亚洲成人av中文| 亚洲女人18毛片水真多| 欧美人在线观看| 99亚洲乱人伦aⅴ精品| 欧美一级中文字幕| 国产91色综合久久免费分享| 久草免费在线视频观看| 日韩一区二区不卡| 蜜臀av在线播放| 国产亚洲一区在线播放| 99综合精品| 国产美女精品久久| 欧美伊人精品成人久久综合97| 成人高清网站| 91免费观看网站| 国内精品嫩模av私拍在线观看| 蜜臀aⅴ国产精品久久久国产老师| 亚洲午夜免费视频| 男人av在线| 国产精品免费看久久久香蕉| 国产精品成人av| 国产成人av免费观看| 亚洲福利视频导航| 日韩欧美在线观看一区二区| 国产精品99久久99久久久二8| 日韩在线高清| 欧美色图校园春色| 亚洲h精品动漫在线观看| 三级视频在线播放| 国产精品麻豆va在线播放| 91精品福利| 三级电影在线看| 欧美午夜影院一区| 中文在线字幕免费观看| 精品国产区在线| 奇米四色…亚洲| 精国产品一区二区三区a片| 亚洲黄色免费三级| 日韩精品免费观看视频| 日韩中文在线字幕| 91农村精品一区二区在线| 中文字幕久久久久| 久久久久久国产精品久久| 欧美女王vk| www.日本久久| 高清一区二区| 成人动漫网站在线观看| 亚洲一级黄色| av免费播放网站| 欧美精品一区二区三区高清aⅴ| 姬川优奈av一区二区在线电影| 成年在线观看视频| 国产欧美一区二区精品性色| 亚洲av无码国产综合专区| 国产精品第一区| 亚洲手机视频|