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()方法从输入流中读取指定数量的字节,并进行后续处理。