【java9】Java9对InputStream类的改进

发布于:2024-05-09 ⋅ 阅读:(21) ⋅ 点赞:(0)

Java9在InputStream支持方面进行了一些改进,引入了新的API和功能,以提供更强大、更灵活的IO和网络编程能力。

InputStream.transferTo()

在java8及之前想要将一个输入流的数据传输到一个输出流,需要写出类似下面的代码:

package com.morris.java9;

import java.io.*;

/**
 * java8及之前将一个输入流的数据传输到一个输出流
 */
public class InputStreamCopyDemo {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("input.txt");
             OutputStream outputStream = new FileOutputStream("output.txt")) {

            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) >= 0) {
                outputStream.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

InputStream的transferTo()方法是Java 9引入的一个方便的方法,用于将数据从一个输入流直接传输到一个输出流。它避免了手动处理缓冲区和循环读取数据的繁琐操作。

下面是使用InputStream.transferTo()方法的示例代码:

package com.morris.java9;

import java.io.*;

/**
 * java9将一个输入流的数据传输到一个输出流
 */
public class InputStreamTransferDemo {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("input.txt");
             OutputStream outputStream = new FileOutputStream("output.txt")) {
            inputStream.transferTo(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在示例代码中,我们创建了一个输入流inputStream,读取名为"input.txt"的文件。然后,我们创建了一个输出流outputStream,将数据传输到名为"output.txt"的文件。

通过调用inputStream.transferTo(outputStream),我们可以直接将输入流中的数据传输到输出流中。这个方法会自动处理读取和写入的缓冲区,以及循环读取数据的过程。在传输完成后,两个流会自动关闭。

需要注意的是,在使用transferTo()方法时,输入流和输出流必须是可关闭的(Closeable),因此我们使用了try-with-resources语句来确保流的正确关闭。

这样,我们就可以简洁而高效地使用transferTo()方法将输入流的数据传输到输出流中。

其实transferTo()只是将我们以前写的代码封装进了一个方法里面而已,transferTo()的源码如下:

public long transferTo(OutputStream out) throws IOException {
    Objects.requireNonNull(out, "out");
    long transferred = 0;
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    int read;
    while ((read = this.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {
        out.write(buffer, 0, read);
        transferred += read;
    }
    return transferred;
}

InputStream.readAllBytes()

Java9引入了InputStream的readAllBytes()方法,它可以一次性将输入流中的所有字节读取到一个字节数组中。使用这个方法可以简化读取输入流的操作,并且在性能上也比较高效。

下面是使用InputStream.readAllBytes()方法的示例代码:

package com.morris.java9;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * java9将输入流的数据读到一个数组中
 */
public class InputStreamReadAllBytesDemo {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("input.txt")) {
            byte[] bytes = inputStream.readAllBytes();
            String content = new String(bytes, StandardCharsets.UTF_8);
            System.out.println(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在示例代码中,我们创建了一个输入流inputStream,读取名为"input.txt"的文件。

通过调用inputStream.readAllBytes(),我们可以一次性将输入流中的所有字节读取到一个字节数组中。然后,我们可以将字节数组转换为字符串,并打印出来。

需要注意的是,在使用readAllBytes()方法时,由于它会一次性读取所有的字节,因此可能会导致内存占用过高的问题,甚至会引起OOM。因此,建议在读取不大的文件时使用这个方法。

这,我们就可以使用readAllBytes()方法简化读取输入流的操作。

其实readAllBytes()方法底层就是调用的下面要介绍的readNBytes()方法:

public byte[] readAllBytes() throws IOException {
    return readNBytes(Integer.MAX_VALUE);
}

InputStream.readNBytes

InputStream的readNBytes()方法是Java9引入的一个方便的方法,用于从输入流中读取指定数量的字节,并将其存储在一个字节数组中。它可以简化读取输入流数据的过程。

下面是使用InputStream.readNBytes()方法的示例代码:

package com.morris.java9;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

/**
 * java9将输入流的指定长度数据读到一个数组中
 */
public class InputStreamReadNBytesDemo {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("input.txt")) {
            byte[] bytes = inputStream.readNBytes(1024);
            String content = new String(bytes, StandardCharsets.UTF_8);
            System.out.println(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在示例代码中,我们创建了一个输入流inputStream,读取名为"input.txt"的文件。然后,我们调用inputStream.readNBytes(1024)方法,从输入流中读取1024个字节,并将它们存储在一个字节数组bytes中。

最后,我们将字节数组转换为字符串,并将其打印到控制台上。

需要注意的是,如果输入流中的字节数不足指定的数量,readNBytes()方法会阻塞直到读取到足够的字节数或到达流的末尾。如果输入流已经到达末尾,readNBytes()方法将返回一个空的字节数组。

这样,我们就可以方便地使用readNBytes()方法从输入流中读取指定数量的字节,并进行后续处理。