流是有序的数据序列,它...
- 提供通用的I / O模型
- 从底层源或目标中提取详细信息
无论您使用流从内存,存储或网络中获取数据,它都将对您隐藏实现细节。详细信息被抽象掉了,因此在每种情况下,您都可以将其视为数据的有序序列。
- 流类型是单向的
这意味着,如果创建Java流的实例,则可以决定是要写入Java实例还是从中读取。您不能在给定的时间同时在单个流上同时执行这两项操作。
我们可以将流分为两类:
- 字节流–作为二进制数据进行交互
- 文本流–作为Unicode字符进行交互
两种Java流类型的常规交互是相同的
用流阅读
正如我们提到的,每个流都用于读取或写入。
首先,让我们看看如何从Java流中读取数据。
在Java中读取二进制数据的基类是。 读取文本数据的基类称为 类。 InputStreamReader
这两个类几乎具有相同的两种方法:
- int read()
- int read(byte/char[] buff)
请注意,在两种情况下,它们都返回一个 Integer 值。这些是解释值。整数是一个32位容器,因此在两种情况下都可以使用。
两者之间的区别:
- 这个InputStream与字节一起工作,字节是8位。
- 这个Reader适用于unicode字符,即16位。
使用InputStream读取字节
InputStream input = // create input stream
int result;
while(result = input.read() >= 0) //Indicates the end-of-stream with a return value of -1
byte byteVal = (byte)result;
// do something with byteVal
};
用阅读器阅读文字
Reader reader = // create reader
int result;
while(result = reader.read() >= 0)//Indicates the end-of-stream with a return value of -1
char charVal = (char)result;
// do something with charVal
};
请注意,如果您想检索该值,则只需将结果转换为适当的类型-在这种情况下为 byte 或 char。
用流写
为了写入数据,有两个基类类似于读流。
- OutputStream(对于字节)
- Writer (用于文本)
用Java流写比读它们更简单。两个类都有一些write方法void return类型
使用OutputStream写入字节
写作OutputStream,可以将单个字节传递给写方法,也可以传递字节数组。
OutputStream output // create output stream;
Byte byteVal = 100;
output.write(byteVal);
byte[] byteBuff = {0, 10, 20};
output.write(byteBuff);
用Writer写
用Writer你可以传递一个简单的字符串,或者一个字符串类write方法
Writer writer // create output stream;
char charVal = 'c';
writer.write(charVal);
char[] charArray = {'c', 'h', 'a', 'r'};
writer.write(charArray);
String stringVal = "String";
writer.write(stringVal);
正如您所看到的,您需要编写的代码比阅读的代码少得多。
常见Java流类
上面,写了有关基本流类的文章。现在更深入地讨论不同的实现。
常见的Input / OutputStream派生类
- ByteArrayInputStream / ByteArrayOutputStream 能够在字节数组上创建流
- PipedInputStream / PipedOutputStream –这很像生产者-消费者的概念。管道输出流可以连接到管道输入流以创建通信管道。管道输出流是管道的发送端。通常,数据是PipedOutputStream通过一个线程写入对象的,而数据是PipedInputStream通过其他线程从连接的对象读取的。
- FileInputStream / FileOutputStream –这些允许在文件上创建流。
常见读/写实现
上面是Reader / Writer流实现的示例。
- CharArrayReader / Writer 允许在字符上创建流
- StringReader / Writer 允许通过字符串创建流。
- PipedReader / Writer 允许以文本的生产者/消费者关系创建流。类似于 PipedOutput / InputStream
- InputStreamReader / Writer 允许通过Input / OutputStream创建流。
- FileReader / Writer 能够在文本文件上进行流传输。
流式错误和清理
到目前为止,我们已经了解了streams的一般特性,但还没有考虑到与它们一起工作的所有实际情况。
Stream Realities
清理
- 流由物理存储支持,物理存储通常存在于Java运行时之外,例如文件或网络连接。
- 因此,Java可能无法可靠地清除,因此我们需要进行可靠的清除。完成处理后,我们需要关闭Streams。
解决
- Streams实现Closeable接口,它实现一个单一的close方法。所以,这是我们的责任。
让我们看看一个简单的解决方案:
Reader reader;
try{
reader = // create output stream;
// do something with reader;
}catch (IOException e) {
//handle exception
}finally {
if(reader != null)
reader.close();
}
上面这个例子的问题是您总是需要实现它。通常,我们经常使用流,所以应该自动完成。让我们看看怎样才能实现。
自动清理
AutoClosable接口:
1、一种方法:关闭
2、接口的基本接口 Closable ,因此每个Stream都支持它。
3、为尝试资源提供支持
Try-With-Resources
1、自动清理一个或多个资源“资源”是可以实现的任何类型
2、AutoClosable语法类似于传统的try语句
3、(可选)包括捕获块处理身体处理关闭方法调用
使用尝试资源
在这里,我提供了一个简单的示例,说明如何通过try-with-resources块使用流的自动关闭。
我将通过来使用它 FileInputStream。稍后我们将讨论这个特定的流。
使用Try-With-Resources
在这里,我提供了一个简单的示例,说明如何通过try-with-resources块使用流的自动关闭。
我将通过来使用它 FileInputStream。稍后我们将讨论这个特定的流。
try(FileInputStream input = new FileInputStream("file1.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
}
用上述方法,无需研究进一步的工作即可关闭流。
概括
在本文中,介绍了Java流的基础知识,它们是什么,它们如何工作以及如何使用它们。