一、IO流
什么是IO流
流是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出,IO流是用来处理设备上的数据,包括文件,磁盘,网络等。
程序需要数据:把数据流入到程序中—>输入.
程序需要保存数据,把数据传递给别人—>输出.
关于流的特性:
1.先进先出:最先写入输出流的数据最先被输入流读取到。
2.顺序存取:可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile除外)
3.只读或只写:每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。
IO流体系
IO流的分类
站在不同的角度,IO的分类方式是不一样的:
- 按数据流的方向:输入流、输出流
- 按处理数据单位:字节流、字符流
- 按功能:节点流、处理流
四大基流:
- 字节输出流OutPutStream
- 字节输入流InPutStream
- 字符输出流Writer
- 字符输入流Reader
四大基流都是抽象类: 其他流都是继承于这四大基流的
我们不能创建四大基流的对象,只能创建其子类对象
由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
二、字节流
字节
一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。
字节输入流【InputStream】
定义:
使用输入流InputStream读取字节,文件输入流即FileInputStream
构建输入流,例如FileInputStream:
ins =new FileInputStream(new File(path));
操控字节输入流的,所用的方法也是针对字节的
常用方法:
int | available() 返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。 |
void | close() 关闭此输入流并释放与该流关联的所有系统资源。 |
void | mark(int readlimit) 在此输入流中标记当前的位置。 |
boolean | markSupported() 测试此输入流是否支持 mark 和 reset 方法 |
abstract int | read() 从输入流中读取数据的下一个字节。 |
int | read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。 |
int | read(byte[] b, int off, int len) 将输入流中最多 len 个数据字节读入 byte 数组 |
void | reset() 将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。 |
long | skip(long n) 跳过和丢弃此输入流中数据的 n 个字节 |
代码示例:
package ChangYL.FileTest.InPutTest;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class InPutTest02 {
public static void main(String[] args) throws Exception {
// 缓冲区
File f1 = new File("d:/d.txt");
InputStream in = new FileInputStream(f1);
// byte[] b=new byte[10];
// //一次最多读取数组长度个字节,读取的内容转换成对应数字存入byte 数组中,
// // 返回的是实际读取的字节数
// int n = in.read(b);
// System. out . println("读取的字节数: "+n);
// String s=new String(b,0,n);
// System. out. println(s);
// byte[] b1=new byte[10];
// //只剩5 个字节,实际读取了5个字节 数组后五个是默认值(无效数据)
// int n1 = in.read(b1);
// System. out . println("读取的字节数: "+n1);
// // 对数组中从0索引开始截取读取到的有效字符数个内容 组成字符串
// String s1=new String(b1,0,n1);
// System. out . println(s1);
// 推荐写法
byte[] b2=new byte[10];
int n;
while ( (n=in.read(b2)) !=-1 ){
String z = new String(b2 ,0,n);
System.out.print(z);
}
}
}
字节输出流【OutputStream】
常用方法:
void | close() 关闭此输出流并释放与此流有关的所有系统资源。 |
void | flush() 刷新此输出流并强制写出所有缓冲的输出字节。 |
void | write(byte[] b) 将 b.length 个字节从指定的 byte 数组写入此输出流。 |
void | write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。 |
abstract void | write(int b) 将指定的字节写入此输出流。 |
代码示例:
//创建文件对象
File f1 = new File("D:/a.txt");
//创建文件
f1.createNewFile();
//创建输出流
OutputStream out = new FileOutputStream(f1);
//准备好的文字
String fint = "abcdef";
//将fint变成byte数组
byte[] bytes = fint.getBytes();
//在目标文件里加入数据
out.write(bytes);
//关闭资源
out.close();
注意:
1)创建字节输出流对象
注意事项:如果文件不存在,就创建;如果文件存在就清空。
2)写数据
注意事项:写出的整数,实际写出的是整数在码表上对应的字母。
3)释放资源
注意事项:每次使用完流必须要释放资源。
综合案例:完成文件的复制
//文件对象
File f1 = new File("D:/a.txt");
File f2 = new File("D:/b.txt");
//创建新文件
f2.createNewFile();
//输入输出对象创建
InputStream in = new FileInputStream(f1);
OutputStream out= new FileOutputStream(f2);
//设置最大读取10个字节
byte[] bytes = new byte[10];
//初始化n
int n;
while ((n=in.read(bytes)) != -1){
//读取a.txt文件内容,然后写入到b.txt文件中
out.write(bytes,0,n);
}