认识IO流
概念:IO,即in
和out
,也就是输入和输出,指应用程序和外部设备之间的数据传递,常见的外部设备包括文件、管道、网络连接。
什么是流?
流(Stream
),是一个抽象的概念,是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通道。
关于流的特性有下面几点:
1:先进先出:最先写入输出流的数据最先被输入流读取到。
2:顺序存取:可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile除外)
3:只读或只写:每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。
IO流的分类?
1:有很多分类方式
1)一种方式是按照流的方向进行分类:
以内存作为参照物,
往内存中去,叫做输入。或者叫做读(Read)。
从内存中出来,叫做输出。或者叫做写(Write)。
2)另一种方式是按照读取数据方式不同进行分类:
有的流是按照字节的方式读取数据,一次读取1个字节byte等同于一次读取8个二进制位。
这种流是万能的,什么类型的文件都可以读取。包括文本文件、图片、声音文件、视频文件等等…
2: IO的类型
虽然java IO类库庞大,但总体来说其框架还是很清楚的。从是读媒介还是写媒介的维度看,Java IO可以分为:
输入流:InputStream和Reader
输出流:OutputStream和Writer
而从其处理流的类型的维度上看,Java IO又可以分为:
字节流:InputStream和OutputStream
字符流:Reader和Writer
IO的分类:
- | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
3:字节流
字节流就是传输单位按为字节进行传输,字符流就是传输按照字符为单位进行传输
字节流:一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。
字节流和字符流的用法几乎完成全一样,区别在于字节流和字符流所操作的数据单元不同,字节流操作的单元是数据单元是8位的字节,字符流操作的是数据单元为16位的字符。
通过上面的介绍我们已经知道,字节流对应的类应该是InputStream和OutputStream,而在我们实际开发中,我们应该根据不同的媒介类型选用相应的子类来处理。
字节流和字符流的其他区别:
字节流一般用来处理图像、视频、音频、PPT、Word等类型的文件。字符流一般用于处理纯文本类型的文件,如TXT文件等,但不能处理图像视频等非文本文件。(字节流可以处理一切文件,而字符流只能处理纯文本文件。)
字节流本身没有缓冲区,缓冲字节流相对于字节流,效率提升非常高。而字符流本身就带有缓冲区,缓冲字符流相对于字符流效率提升就不是那么大了。
字节输出流——OutputStream
第一步:一般的,我们习惯用File类来表示文件对象,也就是创建一个文件对象
File f1 = new File("D:/a.txt");
第二步:OutputStream是一个接口不能直接实现他的构造方法,根据Java多态的特点,使用子类FileOutputStream的构造方法,并在传入File对象
OutputStream out = new FileOutputStream(f1);
第三步:对象创建完成之后就可以使用一些方法
常用方法有:
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();
字节输入流——InputStream
java,io.Inputstream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。
使用InputStream和以上OutputStream步骤一致,不过InputStream的实现类是FileInputStream
常用InputStream的方法功能:
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 个字节。 |
代码示例:
//使用read方法来读取文件里的数据
//创建文件对象
File f1= new File("D:/a.txt");
f1.createNewFile();//创建文件
String s ="直到你降临"; //准备写入的数据
OutputStream out = new FileOutputStream(f1);//创建输出对象
out.write(s.getBytes()); //写入数据
//创建输入流对象
InputStream in = new FileInputStream(f1);
//获取字节
//获取字节返回一个int类型的变量
int read = in.read();
//初始化n
int n;
//使n=read值,当n值不等于-1时,则打印出n的值
while ((n=in.read()) !=-1){
System.out.println(n);
}
综合案例:完成文件的复制
package OutPut;
import java.io.*;
public class CopyFileTest06 {
public static void main(String[] args) throws IOException {
//1,定义源文件和目标文件的File对象
File f1=new File("D:/a.txt");
File newFile=new File("D:/newFile.txt");
//2,定义输入输出流关联文件
InputStream in=new FileInputStream(f1);
OutputStream out=new FileOutputStream(newFile);
byte[] buffer=new byte[10];
int n;
while((n=in.read(buffer)) !=-1){
out.write(buffer,0,n);
}
}
}
运行结果: