博主18年的互联网软件开发经验,从一名程序员小白逐步成为了一名架构师,我想通过平台将经验分享给大家,因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验,晚上进行用心精简、整理、总结、定稿,每天都会整理到12点,为了就是能让大家能够真正了解该技术栈的真正原理,最终从程序员成为一名真正的架构师,写的不一定是全站做好的,但是是全站最用心的~。

以后我会推出一些列的文章,每天都会更新,每天进步一点点,发布顺序【java的api基础、应用、实战】->【java开源技术栈及源码分析】->【java开源技术栈整合】->【java低代码开发平台的建设】

一、java.io

1.30 InputStream

InputStream 是 Java I/O 中用于从输入源(例如文件、网络连接或其他数据源)读取字节流的抽象基类。它是所有字节输入流类的超类。以下是 InputStream 的一些基本介绍、字段、构造方法、方法摘要以及一个简单的使用例子。

InputStream 介绍:
所有字段:
  • static int MAX_SKIP_BUFFER_SIZE 定义了默认的跳过缓冲区大小。

构造方法:

InputStream 是一个抽象类,因此不能被直接实例化。其具体的子类(如 FileInputStreamByteArrayInputStream 等)提供了实际的实现。

方法摘要:
  • int read() 从输入流中读取下一个字节的数据。

  • int read(byte[] b) 从输入流中读取一定数量的字节,存储在指定的字节数组中。

  • int read(byte[] b, int off, int len) 从输入流中读取最多 len 个字节的数据,存储在指定的字节数组中,从偏移量 off 处开始存储。

  • long skip(long n) 跳过输入流中的指定数量的字节。

  • int available() 返回可以从输入流中读取而不受阻塞的字节数。

  • void close() 关闭输入流并释放与之关联的系统资源。

  • void mark(int readlimit) 在当前位置放置标记,并设置最大标记支持的字节数。

  • void reset() 将流的位置重置到上次调用 mark 方法时的位置。

  • boolean markSupported() 判断此输入流是否支持 markreset 方法。

简单使用例子:

以下是一个简单的使用例子,演示如何使用 FileInputStream 从文件中读取字节数据:

javaCopy code
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
​
public class InputStreamExample {
​
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("example.txt")) {
            // 读取单个字节并输出
            int data = inputStream.read();
            while (data != -1) {
                System.out.print((char) data);
                data = inputStream.read();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,我们使用 FileInputStream 打开文件 "example.txt" 并使用 read() 方法读取单个字节,然后将其转换为字符并输出。这个过程重复进行,直到到达文件的末尾(read() 返回 -1)。在实际项目中,可能需要更高级别的输入流,如 BufferedInputStream 进行缓冲,以提高性能。

应用场景:

InputStream 作为字节输入流的抽象基类,广泛用于从不同的数据源中读取字节数据。以下是一些使用场景及相应的代码实现示例:

1. 文件读取:
  • 场景: 从文件中读取字节数据。

  • 代码实现:

    javaCopy code
    try (InputStream inputStream = new FileInputStream("example.txt")) {
        int data;
        while ((data = inputStream.read()) != -1) {
            // 处理读取的字节数据
            System.out.print((char) data);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
2. 网络数据读取:
  • 场景: 从网络连接中读取字节数据。

  • 代码实现:

    javaCopy code
    try (Socket socket = new Socket("example.com", 80);
         InputStream inputStream = socket.getInputStream()) {
    ​
        int data;
        while ((data = inputStream.read()) != -1) {
            // 处理读取的字节数据
            System.out.print((char) data);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
3. 字节数组读取:
  • 场景: 从字节数组中读取数据。

  • 代码实现:

    javaCopy code
    byte[] byteArray = {65, 66, 67, 68, 69}; // Example byte array
    try (InputStream inputStream = new ByteArrayInputStream(byteArray)) {
        int data;
        while ((data = inputStream.read()) != -1) {
            // 处理读取的字节数据
            System.out.print((char) data);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
4. 缓冲流的使用:
  • 场景: 使用缓冲流提高读取性能。

  • 代码实现:

    javaCopy code
    try (InputStream inputStream = new FileInputStream("example.txt");
         BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {
    ​
        int data;
        while ((data = bufferedInputStream.read()) != -1) {
            // 处理读取的字节数据
            System.out.print((char) data);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
5. 数据跳过:
  • 场景: 跳过输入流中的一定数量的字节。

  • 代码实现:

    javaCopy code
    try (InputStream inputStream = new FileInputStream("example.txt")) {
        long skippedBytes = inputStream.skip(10); // Skip 10 bytes
        System.out.println("Skipped " + skippedBytes + " bytes.");
    } catch (IOException e) {
        e.printStackTrace();
    }
6. 标记和重置:
  • 场景: 使用标记和重置功能来回退到先前的读取位置。

  • 代码实现:

    javaCopy code
    try (InputStream inputStream = new FileInputStream("example.txt")) {
        if (inputStream.markSupported()) {
            inputStream.mark(50); // Mark the current position with a read limit of 50 bytes
            int data;
            while ((data = inputStream.read()) != -1) {
                System.out.print((char) data);
                if (data == ' ') {
                    inputStream.reset(); // Reset to the marked position
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

这些例子展示了在不同场景下使用 InputStream 的一些常见用法。在实际应用中,具体的使用方式取决于需求和对字节输入流的定制化需求。

实战例子

在实际项目中,使用 InputStream 的场景可能涉及到从不同来源读取字节数据。以下是一个简单的项目实战例子,演示如何使用 InputStream 读取网络数据并保存到本地文件。

项目要求:
  1. 从指定 URL 获取数据。

  2. 将获取的数据保存到本地文件。

项目实战代码:
javaCopy code
import java.io.*;
import java.net.URL;
​
public class DownloadFileFromUrl {
​
    public static void main(String[] args) {
        String url = "https://example.com/sample.txt";
        String localFilePath = "downloaded_file.txt";
​
        try (InputStream inputStream = new URL(url).openStream();
             BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
             OutputStream outputStream = new FileOutputStream(localFilePath);
             BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream)) {
​
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
                bufferedOutputStream.write(buffer, 0, bytesRead);
            }
​
            System.out.println("File downloaded successfully.");
​
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中,我们通过 URL 类打开一个连接到指定 URL 的输入流,并使用 BufferedInputStream 进行缓冲。然后,我们创建一个本地文件的输出流,并使用 BufferedOutputStream 进行缓冲。通过循环读取输入流的字节并写入输出流,最终将网络数据保存到本地文件。这是一个简单的例子,实际项目中可能需要处理更多的异常、加入错误处理、处理网络连接超时等情况。

01-26 14:49