1.什么是IO流
IO:Input Output
a.介绍
1.Java对数据的操作是通过流的方式,IO流用来处理设备之间的数据传输,上传文件和下载文件,Java用于操作流的对象都在IO包中;
2.流是干什么的? 为了永久性的保存数据
根据数据流向的不同分为输入流和输出流;
根据处理数据类型的不同分为字符流和字节流;
3.InputStream(字节输入流)和Reader(字符输入流)通俗的理解都是读(read)的。
OutputStream(字节输出流)和Writer(字符输出流)通俗的理解都是写(writer)的。
b.结构
InputStream类是字节输入流的抽象类,是所有字节输入流的父类,InputStream类具有层次结构如下图所示;
java中的字符是Unicode编码的,是双字节的。InputStream是用来处理字节的,在处理字符文本时很不方便。Java为字符文本的输入提供了专门的一套类Reader。Reader类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。
输出流OutputStream类是字节输入流的抽象类,此抽象类表示输出字节流的所有类的超类。
Writer类是字符输出流的抽象类,所有字符输出类的实现都是它的子类。
c.分类
为什么用IO流
1.字节流和字符流有什么区别?输入流输出流有什么区别?
字节流和字符流是流的一种划分,按照处理流的数据单位进行的划分。两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入是使用InputStream;在字符流中输出主要是使用Writer类来完成,输入流主要使用Reader类来完成。这四个都是抽象类。
字符流处理的单元为2个字节的Unicode字符,分别是操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。字节流是最基本的,所有的InputStream和OutputStream的子类都是字节流,主要用来处理二进制数据,它是按字节来处理的。但实际中很多数据都是文本,又提出了字符流的概念,它是按虚拟机的编码来处理,也就是说要进行字符集的转化,这两个之间通过InputStreamReader、OutputStreamWriter(转换流)来关联,实际上是通过byte()和String来关联的。
流就像管道一样,在程序和文件之间,输入和输出的方向是针对程序而言,向程序中读入读入东西,就像输入流,从程序中向外读东西,就是输出流。输入流是得到数据,输出流是输出数据。
2.节点流和处理流有什么区别?
节点流和处理流是把流按照功能的另一种划分。
节点流,可以从或向一个特定的地方(节点)读写数据。
处理流是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
3.Word文档能使用字符流操作吗?
不能。因为Word文档不是纯文本文件,除了文字还包含很多格式信息。不能用字符流操作,可以用字节流操作。
4.BufferedInputStream和BufferedOutputStream的特点?
BufferedInputStream和BufferedOutputStream分别是【缓冲】字节输入、输出流,还有【缓冲】字符输入输出流(BufferedReader和BufferedWriter)。
缓冲流是处理流,他不是直接连接数据源/目的地,而是以一个节点流为参数,在节点流的基础上,提供一些简单参数。
先说不带缓冲的流的工作原理吧:它读取到一个字节/字符,就向用户指定的路径写进去,读一个写一个,所以就慢了。带缓冲的流的工作原理:读取到一个字节/字符,先不输出,等凑足了缓冲的最大容量后一次性写进去,从而提高了工作效率。
优点:减少对硬盘的读取次数,降低对硬盘的损耗。
3.怎么实现
1.字节流基类
a.InputStream
InputStream:字节输入流基类,抽象类是表示字节输入流的所有类的超类。
常用方法:
// 从输入流中读取数据的下一个字节 这里需要注意 读取最后一个的值是-1
abstract int read()
// 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b中
int read(byte[] b)
// 将输入流中最多 len 个数据字节读入 byte 数组
int read(byte[] b, int off, int len)
// 跳过和丢弃此输入流中数据的 n个字节
long skip(long n)
// 关闭此输入流并释放与该流
b.OutputStream
OutputStream:字节输出流基类,抽象类是表示输出字节流的所有类的超类。
常用方法:
// 将 b.length 个字节从指定的 byte 数组写入此输出流
void write(byte[] b)
// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流
void write(byte[] b, int off, int len)
// 将指定的字节写入此输出流
abstract void write(int b)
// 关闭此输出流并释放与此流有关的所有系统资源
void close()
// 刷新此输出流并强制写出所有缓冲的输出字节
void flush()
2.字节文件操作流
FileInputStream
FileInputStream:字节文件输入流,从文件系统中的某个文件中获得输入字节,用于读取诸如图像数据之类的原始字节流。
构造方法:
// 通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的File对象file指定
FileInputStream(File file)
// 通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的路径name指定
FileInputStream(String name)
常用方法:覆盖和重写了父类的的常用方法。
.FileOutputStream
FileOutputStream:字节文件输出流是用于将数据写入到File,从程序中写入到其他位置。
// 创建一个向指定File对象表示的文件中写入数据的文件输出流
FileOutputStream(File file)
// 创建一个向指定File对象表示的文件中写入数据的文件输出流
FileOutputStream(File file, boolean append)
// 创建一个向具有指定名称的文件中写入数据的输出文件流
FileOutputStream(String name)
// 创建一个向具有指定name的文件中写入数据的输出文件流
FileOutputStream(String name, boolean append)
常用方法:覆盖和重写了父类的的常用方法。
注;输出的目的地文件不存在,则会自动创建,不指定盘符的话,默认创建在项目目录下;输出换行符时一定要写\r\n不能只写\n,因为不同文本编辑器对换行符的识别存在差异性。
3.字节缓冲流(高效流)
a.BufferedInputStream
BufferedInputStream:字节缓冲输入流,提高了读取效率。
// 创建一个 BufferedInputStream并保存其参数,即输入流in,以便将来使用。
BufferedInputStream(InputStream in)
// 创建具有指定缓冲区大小的 BufferedInputStream并保存其参数,即输入流in以便将来使用
BufferedInputStream(InputStream in, int size)
b.BufferedOutputStream
BufferedOutputStream:字节缓冲输出流,提高了写出效率。
// 创建一个新的缓冲输出流,以将数据写入指定的底层输出流
BufferedOutputStream(OutputStream out)
// 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流
BufferedOutputStream(OutputStream out, int size)
常用方法:
// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此缓冲的输出流
void write(byte[] b, int off, int len)
// 将指定的字节写入此缓冲的输出流
void write(int b)
// 刷新此缓冲的输出流
void flush()
4.字符流
字符流基类
.Reader
Reader:读取字符流的抽象类.
// 读取单个字符
int read()
// 将字符读入数组
int read(char[] cbuf)
// 将字符读入数组的某一部分
abstract int read(char[] cbuf, int off, int len)
// 跳过字符
long skip(long n)
// 关闭该流并释放与之关联的所有资源
abstract void close()
.Writer
Writer:写入字符流的抽象类.
// 写入字符数组
void write(char[] cbuf)
// 写入字符数组的某一部分
abstract void write(char[] cbuf, int off, int len)
// 写入单个字符
void write(int c)
// 写入字符串
void write(String str)
// 写入字符串的某一部分
void write(String str, int off, int len)
// 将指定字符添加到此 writer
Writer append(char c)
// 将指定字符序列添加到此 writer
Writer append(CharSequence csq)
// 将指定字符序列的子序列添加到此 writer.Appendable
Writer append(CharSequence csq, int start, int end)
// 关闭此流,但要先刷新它
abstract void close()
// 刷新该流的缓冲
abstract void flush()
5.字符转换流
.InputStreamReader
InputStreamReader:字节流转字符流,它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
// 创建一个使用默认字符集的 InputStreamReader
InputStreamReader(InputStream in)
// 创建使用给定字符集的 InputStreamReader
InputStreamReader(InputStream in, Charset cs)
// 创建使用给定字符集解码器的 InputStreamReader
InputStreamReader(InputStream in, CharsetDecoder dec)
// 创建使用指定字符集的 InputStreamReader
InputStreamReader(InputStream in, String charsetName)
特有方法:
//返回此流使用的字符编码的名称
String getEncoding()
//使用默认编码
InputStreamReader reader = new InputStreamReader(new FileInputStream("test.txt"));
int len;
while ((len = reader.read()) != -1) {
System.out.print((char) len);// 写出
}
reader.close();
//指定编码
InputStreamReader reader = new InputStreamReader(new FileInputStream("test.txt"),"utf-8");
int len;
while ((len = reader.read()) != -1) {
System.out.print((char) len);//写完
}
reader.close();
.OutputStreamWriter 字节流转字符流
// 创建使用默认字符编码的 OutputStreamWriter
OutputStreamWriter(OutputStream out)
// 创建使用给定字符集的 OutputStreamWriter
OutputStreamWriter(OutputStream out, Charset cs)
// 创建使用给定字符集编码器的 OutputStreamWriter
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
// 创建使用指定字符集的 OutputStreamWriter
OutputStreamWriter(OutputStream out, String charsetName)
特有方法:
//返回此流使用的字符编码的名称
String getEncoding()
5.字符缓冲流(高效流)
BufferedReader:字符缓冲流,从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
// 创建一个使用默认大小输入缓冲区的缓冲字符输入流
BufferedReader(Reader in)
// 创建一个使用指定大小输入缓冲区的缓冲字符输入流
BufferedReader(Reader in, int sz)
特有方法:
// 读取一个文本行
String readLine()
BufferedWriter
字符缓冲流,将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
7.列子:
//1.指定要读 的文件目录及名称
File file =new File("文件路径");
//2.创建文件读入流对象
FileInputStream fis =new FileInputStream(file);
//3.创建缓冲流对象加强fis功能
BufferedInputStream bis =new BufferedInputStream(fis);
//4.定义结束标志,可用字节数组读取
int i =0 ;
while((i = bis.read())!=-1){
//i 就是从文件中读取的字节,读完后返回-1
}
//5.关闭流
bis.close();
//6.处理异常
参考资料:
https://www.cnblogs.com/xll1025/p/6418766.html
https://blog.csdn.net/KK_bluebule/article/details/79157404