IO流是Java中很重要的一部分内容,常用的数据传输,文件的上传和下载都和它分不开。
Java中的IO根据处理数据的方式,可以分为字节流和字符流,同时根据传输方向的不同,又可以分为输入流和输出流。
图中,整理了在Java 8中根据上述分类的IO流,其中字节输入流有28种,字节输出流有18种,字符输入流有9种,字符输出流有8种,看到这么多的流,实际开发中经常使用到的只是其中的一部分。
比如:
在图中已用黑色框图进行了突出标注。
public class FileInputStream extends InputStream
{
//【1】
private final FileDescriptor fd;
//【2】
private final Object closeLock = new Object();
}
代码分析:
FileInputStream是Java IO中的一个类,用于从文件中读取数据。它继承自InputStream类,可以读取字节流。
/**
* 字节流-输入流-FileInputStream
*
*/
public class FileInputStreamTest {
public static void main(String[] args) throws IOException {
File file = new File("/Users/bryantmo/Desktop/code/springcloud_test/webdoor/src/test/java/com/bryant/io/1.txt");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] bytes = new byte[1024];
int read = 0;
// 直接从磁盘读入到内存
while ((read = fileInputStream.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, read));
// 可能再输出到磁盘持久化
}
}
}
public class ByteArrayInputStream extends InputStream {
protected byte buf[];
protected int pos;
}
代码分析:
ByteArrayInputStream 提供了一个从字节数组输入数据的流。主要功能如下:
/**
* 输入流-字节流-ByteArrayInputStream
*/
@Slf4j
public class ByteArrayInputStreamTest {
public static void main(String[] args) throws IOException {
// 被读取的数据,内存
byte[] bytes = "Hello world".getBytes();
// ByteArrayInputStream 是 Java 中的一个类,它是 InputStream 的子类,用于从字节数组中读取数据。
//这个类允许你将一个字节数组视为一个输入流,从而可以使用标准的 I/O 流操作来处理它。
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes, 0, 3);
while (byteArrayInputStream.read() != -1) {
byteArrayInputStream.read(bytes);
log.info("byteArrayInputStream#read: data = {}", new String(bytes));
}
}
}
public class BufferedInputStream extends FilterInputStream {
private static int DEFAULT_BUFFER_SIZE = 8192;
protected volatile byte[] buf;
protected int count;
protected int pos;
}
代码分析:
BufferedInputStream 是 FilterInputStream 的子类,用于对输入流进行缓冲处理。
缓冲输入流可以提高读取效率,因为它减少了与底层数据源的交互次数。
/**
* 输入流-字节流-缓冲输入流
*/
@Slf4j
public class BufferedInputStreamTest {
public static void main(String[] args) throws IOException {
File file = new File("/Users/bryantmo/Desktop/code/springcloud_test/webdoor/src/test/java/com/bryant/io/1.txt");
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 2);
// 设置一个内存
byte[] bytes = new byte[3];
int byteRead;
while ((byteRead = bufferedInputStream.read()) != -1) {
// 直接从磁盘读入数据到内存,非常慢
int read = bufferedInputStream.read(bytes);
log.info("read: data = {}, read = {}", new String(bytes), read);
}
}
}
public class BufferedReader extends Reader {
private Reader in;
private char cb[];
}
代码分析:
BufferedReader该类实现了一个带缓冲区的字符输入流。
/**
* 字符流-输入流-BufferedReader
*/
@Slf4j
public class BufferedReaderTest {
public static void main(String[] args) throws IOException {
File file = new File("/Users/bryantmo/Desktop/code/springcloud_test/webdoor/src/test/java/com/bryant/io/1.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
log.info("line : {}", line);
}
}
}
public class FileOutputStream extends OutputStream
{
private final FileDescriptor fd;
}
代码分析:FileOutputStream类继承OutputStream
/**
* 字节流-输入流-FileOutputStream
*
*/
public class FileOutputStreamTest {
public static void main(String[] args) throws IOException {
String data = "字节流-输入流-FileInputStream";
// 文件标识符
File file = new File("/Users/bryantmo/Desktop/code/springcloud_test/webdoor/src/test/java/com/bryant/io/1.txt");
FileOutputStream fileInputStream = new FileOutputStream(file);
// 直接从内存写入磁盘
fileInputStream.write(data.getBytes());
fileInputStream.flush();
}
}
public class ByteArrayOutputStream extends OutputStream {
/**
* The buffer where data is stored.
*/
protected byte buf[];
protected int count;
}
ByteArrayOutputStream的部分属性:
/**
* 字节流-输出流-ByteArrayOutputStream
*/
@Slf4j
public class ByteArrayOutputStreamTest {
public static void main(String[] args) throws IOException {
String newString = "Hello, World!";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 底层是for循环,写入ByteArrayOutputStream的内存数组
baos.write(newString.getBytes());
// 读出内存数组:底层会新建一个数组,通过数组拷贝,并返回
byte[] bytes = baos.toByteArray();
log.info("bytes: {}", bytes);
log.info("string: {}", new String(bytes));
}
}
public class BufferedOutputStream extends FilterOutputStream {
/**
* The internal buffer where data is stored.
*/
protected byte buf[];
protected int count;
}
BufferedOutputStream的部分属性:
/**
* 输出流-字节流-BufferedOutputStream
* BufferedOutputStream通过内部维护一个缓冲区来减少对底层文件系统的调用次数,从而提高写入效率。
*/
@Slf4j
public class BufferedOutputStreamTest {
public static void main(String[] args) throws IOException {
// 设置一个内存数据
String data = "Hello world...." + System.currentTimeMillis();
// 输出流写入字符到磁盘
File file = new File("/Users/bryantmo/Desktop/code/springcloud_test/webdoor/src/test/java/com/bryant/io/1.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file);
// 这里我们测试了,缓冲区大小为2和222的预设值时,分别对应了底层不同的写入磁盘逻辑
// BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream, 2);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream, 222);
bufferedOutputStream.write(data.getBytes());
// flush()方法用于强制将缓冲区中的数据写入到底层的文件输出流中。即使缓冲区未满,调用flush()也会立即执行写入操作。
bufferedOutputStream.flush();
}
}
public class BufferedWriter extends Writer {
private Writer out;
private char cb[];
}
BufferedWriter
是 Java 中的一个类,用于高效地写入字符数据到文件或其他输出流。
它通过在内存中维护一个缓冲区来减少对底层资源的访问次数,从而提高写入性能。
BufferedWriter
的核心优势在于其缓冲区机制。当你调用 write
方法时,数据首先被写入内存中的缓冲区,而不是直接写入底层输出流。只有当缓冲区满、显式调用 flush
方法或关闭流时,数据才会被写入底层输出流。这种机制减少了 I/O 操作的次数,从而提高了写入性能。
/**
* 字符流-输出流-BufferedWriter
*/
@Slf4j
public class BufferedWriterTest {
public static void main(String[] args) throws IOException {
String data = "hello world";
File file = new File("/Users/bryantmo/Desktop/code/springcloud_test/webdoor/src/test/java/com/bryant/io/2.txt");
FileWriter fileWriter = new FileWriter(file);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
try {
bufferedWriter.write(data);
bufferedWriter.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。