输入和输出是相对于程序的:
流的分类:
第一:
输入流: 数据从外部流入写的程序
输出流: 数据从程序流到外面
第二:
从流结构上:其实底层都是以字节流来实现的。
**字节流:
字符流**:在字节流的基础上做了封装,相当于直接操作字符串一样,简化操作。
字节流**byte Stream的输入和输出基础是 **InputStream 和 OutoutStream这两个抽象类 字节的输入和输出是由这两个类的子类实现的。
使用字节流读取或者写入二进制数据
字符流 character Stream 的输入和输出基础是 抽象类 Reader 和 Writer, 采用了统一的编码标准,因而可以国际化。
读数据的逻辑:
1. open a stream
2. while more information{ read information }
3. close the stream
第三:
节点流:从特定的地方读写的流,比如从某一块磁盘
过滤流:使用节点流作为输入和输出,过滤流是使用一个已经存在的输入流或者输出流创建的,对节点流的信息进行过滤,包装
比较常用的几个流 :
FileInputStream 和FileOutputStream // 文件流
BufferedInputStream 和 BufferedOutputStream //带缓冲的文件流
DateInputStream 和 DataOutputStream //操作数据类型的文件流
ByteArrayInputStream 和 ByteArrayOutputStream // 字节数组流,有时会用到
InputStream:
三个基本的读方法:
abstract read() // 是一个抽象方法, 供子类实现
// 为什么只有这一个read方法是抽象的,而其他两个read是具体的,
// 解释:其他两个read 方法都是直接或者间接根据第一个方法实现的,只有第一个read方法是跟具体的I/O设备相关的,它需要通过子类实现。
int read(byte[] b) // 将数据读入一个字节数组,如果返回-1,表示读取到了输入流的末尾
int read(byte[] b ,int off, int len) // 将数据读入一个字节数组, off 指定在数组b 中存放数据的起始偏移位置,len 指定读取的最大字节数。
如果返回-1,表示读取到了输入流的末尾。
例子: 从文件中读取数据
// 从一个文件中读取信息 ,非常固定的一个写法,流程记住
public class FileInputStreamTest {
public static void main(String[] args) throws IOException {
File file = new File("G:/a2.txt");
InputStream in = new FileInputStream(file);
byte[] byteData = new byte[200];
// 从in 这个流中读取数据,每次最多读取200个字节,赋给byteData,
// 返回值是一次实际读取的字节个数赋给length, 比如现在的流中只有150个字节,则第一次循环的时候length = 150