---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
概述:
1、IO流:即Input Output的缩写。
2、特点:
1)IO流用来处理设备间的数据传输。
2)Java对数据的操作是通过流的方式。
3)Java用于操作流的对象都在IO包中。
4)流按操作数据分为两种:字节流和字符流。
5)流按流向分为:输入流和输出流。
注意:流只能操作数据,而不能操作文件。
3、IO流的常用基类:
1)字节流的抽象基流:InputStream和OutputStream
2)字符流的抽象基流:Reader和Writer
注:此四个类派生出来的子类名称都是以父类名作为子类名的后缀,以前缀为其功能;如InputStream子类FileInputStream和Reader子类FileReader
------------------------------------------------------------------------------------------------------------
字符流,有用来操作文件的FileWriter,FileReader子类
------------------------------------------------------------------------------------------------------------
import java.io.*;
public class TestIO {
/**
* 拷贝一个文件
*/
public static void main(String[] args) {
/*
*1. 因不知文件的具体的哪种类型数据,使用字符流,不使用字节流
*2.采用边输入(Reader),边输出(Writer)的方式,拷贝
* */
FileReader fr=null;
FileWriter fw=null;
char ch[]=null;
int length=0;
try {
fr=new FileReader("src/testCopy.txt");/*可以用"/"但用反的只能用"\\",用new File("d:/xx","c.txt")后参可变*/
fw=new FileWriter("D:\\copy.txt");//这里无须确定,目录下有没有存在文件名相同的文件,如果有也覆盖了
ch=new char[1024];
length=fr.read(ch);//先读
while(length!=-1){
fw.write(ch, 0, length);//再写
length=fr.read(ch);//读
}
System.out.println("拷贝成功");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {//关闭流
if(fr!=null)
fr.close();
if(fw!=null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
注:
--close()和flush()区别:flush()刷新后,流可以继续使用;而close()刷新后,将会关闭流,不可再写入字符流。
--其实java自身不能写入数据,而是调用系统内部方式完成数据的书写,使用系统资源后,一定要关闭资源。
--数据的续写是通过构造函数 FileWriter(String s,boolean append),根据给定文件名及指示是否附加写入数据的boolean值来构造FileWriter对象。
2、读取字符流:
1)创建一个文件读取流对象,和指定名称的文件相关联。要保证该文件已经存在,若不存在,将会发生异常FileNotFoundException。
2)调用读取流对象的read()方法。read():一次读一个字符,且会继续往下读。
第一种方式:读取单个字符。第二种方式:通过字符数组进行读取。
3)读取后要将流资源关闭。
1.BufferedWriter,BufferedReader,在FileReader,FileWriter之后加BufferedReader bufr=new BufferedReader(fr);,通过bufr来操作
BufferedWriter,BufferedReader是通过,装饰模式,来加强的,例:
class Person{
public void save(){
System.out.print("sava");
}
}
class SuperPerson{
private Person person;
SuperPerson(Person p){this.person=p;}
public void save(){//方法功能上的加强
System.out.print("先准备");
person.save();
System.out.print("后处理");
}
}
详细步骤,及说明:
1、缓冲区的出现:提高了流的读写效率,所以在缓冲区创建前,要先创建流对象,即先将流对象初始化到构造函数中。
2、缓冲技术原理:此对象中封装了数组,将数据存入,在一次性取出。
3、写入流缓冲区BufferedWriter的步骤:
1)创建一个字符写入流对象
2)为提高字符写入流效率,加入缓冲技术,只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
注意,只要用到缓冲去就需要刷新。
3)其实关闭缓冲区就是在关闭缓冲区中的流对象。
--->该缓冲区中提供了一个跨平台的换行符:newLine()。
4、读取流缓冲区BufferedReader的步骤:
1)创建一个读取流对象和文件关联
2)为提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数。
3)该缓冲区提供了一个一次读一行的方法readLine(),方便与对文本数据的获取,当返回null时,表示读到文件末尾。
readLine()方法返回的时只返回回车符之前的数据内容,并不返回回车符,即读取的内容中不包含任何行终止符(回车符和换行符)。
--->readLine()方法原理:无论是读一行,或读取多个字符,其实最终都是在硬盘上一个一个读取。所以最终使用的还是read方法一次读一个。
-----------------------------------------------------------------
字节流,子类FileInputStream,FileOutputStream来处理媒体文件
----------------------------------------------------------------
字节流:
1、字节流和字符流的原理是相似的,多用于对媒体进行操作。
2、由于媒体数据中都是以字节存储的,所以,字节流对象可直接对媒体进行操作,而不用再进行刷流动作。
3、读写字节流:InputStream 输入流(读)相对于程序而言的
OutputStream 输出流(写)
4、为何不用进行刷流动作:
因为字节流操作的是字节,即数据的最小单位,不需要像字符流一样要进行转换为字节。可直接将字节写入到指定文件中,但是需要在写代码的时候,如果有字符串,要将字符串转为字节数组再进行操作。
5、特有方法:
int available() ---> 放回数据字节的长度,包含终止符
在定义字节数组长度的时候,可以用到这个方法:byte[] = new byte[fos.available()] (fos为字节流对象)
但是,对于这个方法要慎用,如果字节过大(几个G),那么如此大的数组就会损坏内存,超过jvm所承受的大小(指定内存为64M)。
例:
import java.io.*; class CopyPicture{ public static void main(String[] args) { FileOutputStream fos = null; FileInputStream fis = null; try { // 创建读写流对象 fos = new FileOutputStream("cope.gif"); fis = new FileInputStream("my.gif"); int len = 0; // 定义字节数组,存储读取的字节流 byte[] arr = new byte[1024]; // 循环读写流,完成数据存储 while ((len = fis.read(arr)) != -1) { fos.write(arr, 0, len); } } catch (IOException e) { throw new RuntimeException("复制Picture失败"); } // 关闭资源 finally { if (fos != null) { try { fos.close(); } catch (IOException e) { throw new RuntimeException("写入流关闭失败"); } } if (fos != null) { try { fis.close(); } catch (IOException e) { throw new RuntimeException("读取流关闭失败"); } } } } }