一,IO流概述
1,IO流
即InputOutput的缩写,用于处理设备上的数据。流,可以理解为数据的流动,就是一个数据流。IO流最终要以对象来体现,对象都存在于IO包中。
2,特点
1)IO流用来处理设备间的数据传输。
2)Java对数据的操作是通过流的方式。
3)Java用于操作流的对象都在IO包中。
4)流按操作数据分为两种:字节流和字符流。
5)流按流向分为:输入流和输出流。
注意:流操作的是数据,而不是文件,而且流的操作只有两种:读和写。
3,流的分类
1) 输入流(读)和输出流(写)。
2) 因为处理的数据不同,又可以分为字节流和字符流。
4,流的常用基类
1)字节流的抽象基类:InputStream和OutputStream
2)字符流的抽象基类:Reader和Writer
它们的子类,都有一个共性特点:子类名后缀都是父类名,前缀名都是这个子类的功能名称。
二,字符流
1, 简述
字符流中的对象融合了编码表。使用的是默认的编码,即当前系统的编码。字符流只用于处理文字数据,而字节流可以处理媒体数据。
2,基类介绍
2.1 Reader:
用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。
|---BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
|---LineNumberReader:跟踪行号的缓冲字符输入流。此类定义了方法setLineNumber(int)和getLineNumber(),它们可分别用于设置和获取当前行号。
|---InputStreamReader:是字节流通向字符流的桥梁:它使用指定的charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
|---FileReader:用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。
|---CharArrayReader:
|---StringReader:
2.2 Writer:
写入字符流的抽象类。子类必须实现的方法仅有write(char[], int, int)、flush() 和 close()。
|---BufferedWriter:将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
|---OutputStreamWriter:是字符流通向字节流的桥梁:可使用指定的charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
|---FileWriter:用来写入字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的。要自己指定这些值,可以先在 FileOutputStream上构造一个 OutputStreamWriter。
|---PrintWriter:
|---CharArrayWriter:
|---StringWriter:
三,字节流
1、字节流和字符流的基本操作是相同的,但字节流还可以操作其他媒体文件。
2、由于媒体文件数据中都是以字节存储的,所以,字节流对象可直接对媒体文件的数据写入到文件中,而可以不用再进行刷流动作。
3、读写字节流:
InputStream 输入流(读)
OutputStream 输出流(写)
4,InputStream 输入流
InputStream:是表示字节输入流的所有类的超类。
|--- FileInputStream:从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader。
|--- FilterInputStream:包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。
|--- BufferedInputStream:该类实现缓冲的输入流。
|--- Stream:
|--- ObjectInputStream:
|--- PipedInputStream:
5,OutputStream 输出流
OutputStream:此抽象类是表示输出字节流的所有类的超类。
|--- FileOutputStream:文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。
|--- FilterOutputStream:此类是过滤输出流的所有类的超类。
|--- BufferedOutputStream:该类实现缓冲的输出流。
|--- PrintStream:
|--- DataOutputStream:
|--- ObjectOutputStream:
|--- PipedOutputStream:
四,流的操作规律
因为功能的不同,流的体系中有非常多的对象。那么我们在开发中到底该用哪个对象更合适呢?这就要求我们明确流的操作规律。
1,明确源和目的。
数据源:就是需要读取,可以使用两个体系:InputStream、Reader;
数据汇:就是需要写入,可以使用两个体系:OutputStream、Writer;
2,操作的数据是否是纯文本数据?
如果是:数据源:Reader
数据汇:Writer
如果不是:数据源:InputStream
数据汇:OutputStream
3,虽然确定了一个体系,但是该体系中有太多的对象,到底用哪个呢?
明确操作的数据设备。
数据源对应的设备:硬盘(File),内存(数组),键盘(System.in)
数据汇对应的设备:硬盘(File),内存(数组),控制台(System.out)。
4,需要在基本操作上附加其他功能吗?比如缓冲。
如果需要就进行装饰。
5,转换流
5.1转换流的特点
字符流与字节流之间的桥梁
方便了字符流与字节流之间的操作
5.2转换流的应用:
节流中的数据都是字符时,转成字符流操作更高效。
5.3转换流特有功能:
转换流可以将字节转成字符,原因在于,将获取到的字节通过查编码表获取到指定对应字符。
转换流的最强功能就是基于 字节流 + 编码表 。没有转换,没有字符流。
注意:凡是操作设备上的文本数据,涉及编码转换,必须使用转换流。
5.4 InputStreamReader
将字节流通向字符流。
a、获取键盘录入对象。
InputStreamin=System.in;
b、将字节流对象转成字符流对象,使用转换流。
InputStreamReaderisr=newInputStreamReader(in);
c、为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
BufferedReaderbr=newBufferedReader(isr);
//键盘录入最常见写法
BufferedReaderin=newBufferedReader(new InputStreamReader(System.in));
5.5 OutputStreamWriter
字符流通向字节流。
字符通向字节:录入的是字符,存到硬盘上的是字节。步骤和InputStreamReader转换流一样。
示例:
/*
需求:将键盘录入的数据,显示在控制台,当输入end时,结束 程序
数据源:键盘录入。
输出:控制台。
*/
import java.io.*;
class TransStreamTest
{
public static void main(String[] args)throws IOException
{
//键盘录入最常见写法
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
//字符流通向字节流
BufferedWriter bw =new BufferedWriter(new OutputStreamWriter(System.out));
System.out.println("请输入数据,按回车键确认,输入end结束程序");
String s=null;
while((s=in.readLine())!=null)
{
if("end".equals(s))
break;
bw.write(s.toUpperCase());//转换成大写并写入数据
bw.newLine();//换行
bw.flush();//刷新 缓冲区
}
bw.close();//关闭流
in.close();
}
}
五, 代码示例
1,/*
* 将一个已有的文件,转成大写,保存到另一个文件中
* */
import java.io.*;
public class IoTest2{
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
BufferedReader bufr =
new BufferedReader(new InputStreamReader(new FileInputStream("CopyFile.java")));//读取一个已存在的java文件
BufferedWriter bufw =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("copyfile.txt")));//保存为一个txt文件
String line = null;
while((line=bufr.readLine())!=null){
bufw.write(line.toUpperCase());//转换为大写
bufw.newLine();
bufw.flush();
}
bufw.close();
bufr.close();
}
}
2,
/*
* 将一个多媒体文件复制并保存
* */
import java.io.*;
class OtherTest
{
public static void main(String[] args) throws IOException
{
copy_1();
copy_2();
copy_3();
}
public static void copy_3()throws IOException
{
FileInputStream fis = new FileInputStream("c:\\1.mp3");
FileOutputStream fos = new FileOutputStream("c:\\4.mp3");
int by = 0;
while((by = fis.read())!=-1)
{
fos.write(by);
}
fos.close();
fis.close();
}
public static void copy_2()throws IOException
{
FileInputStream fis = new FileInputStream("c:\\1.mp3");
BufferedInputStream bufis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("c:\\3.mp3");
BufferedOutputStream bufos = new BufferedOutputStream(fos);
int by = 0;
while((by = bufis.read())!=-1)
{
bufos.write(by);
}
bufos.close();
bufis.close();
}
public static void copy_1()throws IOException
{
FileInputStream fis = new FileInputStream("c:\\1.mp3");
//int len = fis.available();//获取和流相关联的文件的字节数
FileOutputStream fos = new FileOutputStream("c:\\2.mp3");
byte[] buf = new byte[fis.available()];//定义一个刚刚好大小的数组。对于小体积数据可以使用。
//也可以作为获取文件体积的依据。
fis.read(buf);// 将所有数据存储到该数组中。
fos.write(buf);//将数组中的数据写入目的地中。
fis.close();
}
}