按照数据流向的不同:输入流、输出流
按照处理数据的单位的不同:字节流 、字符流(处理的文本文件,若处理视频、图像、音频等文件只能用字节流)
按照角色的不同:节点流(直接作用于文件)、处理流(也叫过滤流)
节点流:可以从或向一个特定的地方(节点)读写数据。
处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
通常代表拥有某种功能 但也要通过结点流实现其功能 比如 字节 与 字符 相互转化等
如图:
抽象基类:InputStream、OutputStream、Reader、Writer
常用的流:
节点流:FileInputStream、FileOutputStream、FileReader、FileWriter
缓冲流(处理流的一种):BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWrite
转换流(处理流的一种):InputStreamReader(解码:用于当字节流中的数据都为字符时候,转成字符流操作,使效率更高。)、OutoutStreamWriter(编码:上个过程的逆过程)。字节字符流的相互转换。
打印流:PrintStream(字节流)、PrintWriter(字符流)。只有输出。
对象流:ObjectInputStream、ObjectOutputStream。用于存储和读取对象的处理流,它可以把java中的对象写入到数据源,也能把对象从数据源中还原回来。序列化中会用到。
标准输入输出流:System.out、System.in
…
java的IO流工涉及40多个类,实际上非常规则,都是从4个抽象基类派生的。命名规则也是很有规律的,都是以抽象基类为后缀名。其中以InputStream、OutputStream后缀的都是以字节为单位的(字节流),以Reader、Writer为后缀的都是以字符为单位的(字符流)。根据不同的需求功能选用不同的流是很有必要的,各流在什么时候使用是由它们的特点决定的。比如我们要处理纯文本文件,用字符流最高效。
FileInputOutputStream例子:
public class TestFileInputOutputStream {
@Test
public void testCopyFile(){
long start = System.currentTimeMillis();
String src = "dbcp.txt";
String dest = "dbcp2.txt";
copyFile(src,dest);
long end = System.currentTimeMillis();
System.out.println("花费的时间为:" + (end - start));//3198
}
// 实现文件复制的方法
public void copyFile(String src, String dest) {
// 1.提供读入、写出的文件
File file1 = new File(src);
File file2 = new File(dest);
// 2.提供相应的流
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(file1);
fos = new FileOutputStream(file2);
// 3.实现文件的复制
byte[] b = new byte[1024];
int len;
while ((len = fis.read(b)) != -1) {
// fos.write(b);//错误的写法两种: fos.write(b,0,b.length);
fos.write(b, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 从硬盘读取一个文件,并写入到另一个位置。(相当于文件的复制)
@Test
public void testFileInputOutputStream() {
// 1.提供读入、写出的文件
File file1 = new File("C:\\Users\\shkstart\\Desktop\\1.jpg");
File file2 = new File("C:\\Users\\shkstart\\Desktop\\2.jpg");
// 2.提供相应的流
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(file1);
fos = new FileOutputStream(file2);
// 3.实现文件的复制
byte[] b = new byte[20];
int len;
while ((len = fis.read(b)) != -1) {
// fos.write(b);//错误的写法两种: fos.write(b,0,b.length);
fos.write(b, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// FileOutputStream
@Test
public void testFileOutputStream() {
// 1.创建一个File对象,表明要写入的文件位置。
// 输出的物理文件可以不存在,当执行过程中,若不存在,会自动的创建。若存在,会将原有的文件覆盖
File file = new File("hello2.txt");
// 2.创建一个FileOutputStream的对象,将file的对象作为形参传递给FileOutputStream的构造器中
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
// 3.写入的操作
fos.write(new String("I love China!").getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 4.关闭输出流
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Test
public void testFileInputStream() {
FileInputStream fis = null;
try {
File file = new File("hello.txt");
fis = new FileInputStream(file);
byte[] b = new byte[5];// 读取到的数据要写入的数组。
int len;// 每次读入到byte中的字节的长度
while ((len = fis.read(b)) != -1) {
// for (int i = 0; i < len; i++) {
// System.out.print((char) b[i]);
// }
String str = new String(b, 0, len);
System.out.print(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Reader和Weiter示例
使用FileReader、FileWriter 可以实现文本文件的复制。
对于非文本文件(视频文件、音频文件、图片),只能使用字节流!
public class TestFileReaderWriter {
@Test
public void testFileReaderWriter(){
//1.输入流对应的文件src一定要存在,否则抛异常。输出流对应的文件dest可以不存在,执行过程中会自动创建
FileReader fr = null;
FileWriter fw = null;
try{
File src = new File("dbcp.txt");
File dest = new File("dbcp1.txt");
//2.
fr = new FileReader(src);
fw = new FileWriter(dest);
//3.
char[] c = new char[24];
int len;
while((len = fr.read(c)) != -1){
fw.write(c, 0, len);
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(fw != null){
try {
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fr != null){
try {
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Test
public void testFileReader(){
FileReader fr = null;
try {
File file = new File("dbcp.txt");
fr = new FileReader(file);
char[] c = new char[24];
int len;
while((len = fr.read(c)) != -1){
String str = new String(c, 0, len);
System.out.print(str);
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(fr != null){
try {
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
缓冲流示例代码:
public class TestBuffered {
@Test
public void testBufferedReader(){
BufferedReader br = null;
BufferedWriter bw = null;
try {
File file = new File("dbcp.txt");
File file1 = new File("dbcp3.txt");
FileReader fr = new FileReader(file);
FileWriter fw = new FileWriter(file1);
br = new BufferedReader(fr);
bw = new BufferedWriter(fw);
String str;
while((str = br.readLine()) != null){
bw.write(str + "\n");
bw.flush();
}
}catch (IOException e) {
e.printStackTrace();
}finally{
if(bw != null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(br != null){
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Test
public void testCopyFile(){
long start = System.currentTimeMillis();
String src = "C:\\Users\\shkstart\\Desktop\\实验.doc";
String dest = "C:\\Users\\shkstart\\Desktop\\实验1.doc";
copyFile(src,dest);
long end = System.currentTimeMillis();
System.out.println("花费的时间为:" + (end - start));//746
}
//使用缓冲流实现文件的复制的方法
public void copyFile(String src,String dest){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1.提供读入、写出的文件
File file1 = new File(src);
File file2 = new File(dest);
//2.想创建相应的节点流:FileInputStream、FileOutputStream
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
//3.将创建的节点流的对象作为形参传递给缓冲流的构造器中
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//4.具体的实现文件复制的操作
byte[] b = new byte[1024];
int len;
while((len = bis.read(b)) != -1){
bos.write(b, 0, len);
bos.flush();
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//5.关闭相应的流
if(bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bis != null){
try {
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//使用BufferedInputStream和BufferedOutputStream实现非文本文件的复制
@Test
public void testBufferedInputOutputStream(){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//1.提供读入、写出的文件
File file1 = new File("1.jpg");
File file2 = new File("2.jpg");
//2.想创建相应的节点流:FileInputStream、FileOutputStream
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
//3.将创建的节点流的对象作为形参传递给缓冲流的构造器中
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//4.具体的实现文件复制的操作
byte[] b = new byte[1024];
int len;
while((len = bis.read(b)) != -1){
bos.write(b, 0, len);
bos.flush();
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//5.关闭相应的流
if(bos != null){
try {
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(bis != null){
try {
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
代码中访问的文件需要自己创建