------- android培训、java培训、期待与您交流! --------
字符流和字节流
字节流两个基类:
InputStream OutputStream
字符流两个基类
Reader Writer
字符流的特点
既然IO流是用于操作数据的,那么数据的最常见体现形式是,文件。
步骤:
创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。而且该文件会被创建到指定目录下,如果该目录下已有同名文件,将被覆盖。
调用write方法,将字符串写入到流中。
刷新流对象中的缓冲中的数据。将数据刷到目的地中。fw.flush();
或者关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据。将数据刷到目的地中。fw.close();
和flush的区别
flush刷新后,流可以继续使用,close刷新后,会将流关闭。
文本文件读取方式
1,创建一个文件读取流对象,和指定名称的文件相关联。
要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException。
调用读取流对象的read方法。
read();一次读一个字符,而且会自动往下读。
2,通过字符数组进行读取。
定义一个字符数组,用于存储读到的字符。
该read(char[])返回的是读到的字符个数。
拷贝文本文件
复制的原理:其实就是讲C盘下的文件数据存储到D盘的一个文件中。
步骤:
1,在D盘创建一个文件,用于存储C盘文件中的数据。
2,定义读取流和C盘文件关联。
3,通过不断的读写完成数据存储。
4,关闭资源。
缓冲区
缓冲区的出现是为了提高流的操作效率。所以在创建缓冲区之前,必须要先有流对象。
FileWriter fw = new FileWriter("buf.txt");
然后把需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
BufferedWriter bufw = new BufferedWriter(fw);
关闭缓冲区,就是在关闭缓冲区中的流对象。
bufw.close();
该缓冲区中提供了一个跨平台的换行符newLine();
字符流读取缓冲区:
该缓冲区提供了一个一次读一行的方法readLine(),方便于对文本数据的获取。
当返回NULL时,表示读到文件末尾。
readLine方法返回的时候只返回回车符之前的数据内容,并不返回回车符。
readLine方法原理:
无论是读一行,或者读取多个字符,其实最终都是在硬盘上一个一个读取,还是使用read方法一次读一个的方法。
装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
那么自定义的该类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。
装饰和继承:装饰模式比继承要灵活,避免了继承体系臃肿,而且降低了类与类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能。
所以装饰类和被装饰类通常都是属于一个体系中的。
字符流:FileWriter FileReader BufferedReader BufferedWriter
字节流:InputStream OutputStream BufferedInputStream BufferedOutputStream
读取键盘录入:
System.out :对应的是标准输出设备,控制台。
System.in :对应的是标准输入设备,键盘。
将字节流对象转成字符流对象,使用转换流。
InputStreamReader isr = new InputStreamReader(System.in);
为了提高效率,将字符串进行缓冲区技术高效操作,使用BufferedReader。
BufferedReader bufr = new BufferedReader(isr);
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
流操作的基本规律,通过三个明确来完成。
1,明确源和目的。
源:输入流。InputStream Reader
目的:输出流。OutputStream Writer
2,操作的数据是否是纯文本。
是:字符流。
不是:字节流。
3,当体系明确后,在明确要使用哪个具体的对象。
通过设备来进行区分:
源设备:内存,硬盘,键盘。
目的设备:内存,硬盘,控制台。
1,将一个文本文件中数据存储到另一个文件中。复制文件。
源:因为是源,所以使用读取流。InputStream Reader
是不是操作文本文件?是!这时就可以选择Reader,这样体系就明确了。
接下来明确要使用该体系中的哪个对象。
明确设备:硬盘。
是否需要提高效率?是!加入Reader体系中缓冲区BufferedReader。
Reader体系中可以操作文件的对象是FileReader。
FileReader fr = new FileReader("a.txt");
BufferedReader bufr = new BufferedReader(fr);
目的:OutputStream Writer
是否是纯文本?是!Writer。
设备:硬盘,一个文件。
Writer体系中可以操作文件的对象FileWriter。
是否需要提高效率?是!加入Reader体系中缓冲区BufferedReader。
FileWriter fw = new FileWriter("b.txt");
BufferedWriter bufw = new BufferedWriter(fw);
2,需求:将键盘录入的数据保存到一个文件中。
这个需求中有源和目的都存在。
那么分别分析
源:InputStream Reader
是不是纯文本?是!Reader。
设备:键盘。对应的对象是System.in。
为了操作键盘的文本数据方便,转成字符流按照字符串操作是最方便的。
所以既然明确了Reader,那么就将System.in转换成Reader。
用了Reader体系中的转换流,InputStreamReader。
InputStreamReader isr = new InputStreamReader(System.in);
需要提高效率吗?需要!BufferedReader。
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream Writer
是否是纯文本?是!Writer。
设备:硬盘。一个文件,使用FileWriter。
FileWriter fw = new FileWriter("c.txt");
需要提高效率吗?需要!
BufferedWriter bufw = new BufferedWriter(fw);
********
扩展一下,想要把录入的数据按照指定的编码表(utf-8),将数据存到文件中。
目的:OutputStream Writer
是否是纯文本?是!Writer。
设备:硬盘。一个文件,使用FileWriter。
但是FileWriter是使用的默认编码表,GBK。
但是存储时,需要加入指定编码表utf-8。而指定的编码表只有转换流可以指定。
所以要使用的对象是OutputStreamWriter。
而该转换流对象要接收一个字节输出流,而且还可以操作文件的字节输出流。FileOutputStream。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
需要高效吗?需要!
BufferedWriter bufw = new BufferedWriter(osw);
所以,记住,转换流什么时候使用。字符和字节之间的桥梁,通常涉及到字符编码转换时,需要使用转换流。
File类常见方法:
1,创建。
boolean createNewFile():在指定位置创建文件,如果该文件已经存在,则不创建,返回false。
和输出流不一样,输出流对象一建立就创建文件,如果文件存在,会覆盖。
2,删除。
boolean delete():删除失败返回false。
void deleteOnExit():在程序退出时删除指定文件。
3,判断。
boolean exists():文件是否存在。
isFile();
isDirectory();
isHidden();
isAbsolute();
4,获取信息。
getName();
getPath();
getParent();
getAbsolutePath();
long lastModified();
long length();
Properties是hashtable的子类。
也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串。
是集合中和IO技术相结合的集合容器。
该对象的特点:可以用于键值对形式的配置文件。
打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印。
字节打印流:
PrintStream
构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
字符打印流:PrintWriter构造函数可以接收的参数类型:
1,file对象。File
2,字符串路径。String
3,字节输出流。OutputStream
4,字符输出流。Writer
RandomAccessFile
该类不算是IO体系中的子类,而是直接继承自Object。
但是它是IO包中的成员,因为它具备读和写的功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针位置,同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。而且操作文件还有模式:只读r,读写rw等。
如果模式为只读r,不会创建文件,会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式为rw,而且该对象的构造函数要操作的文件不存在,会自动创建,如果存在则不会覆盖。
DataInputStream与DataOutputStream
可以用于操作基本数据类型的数据的流对象。
用于操作字节数组的流对象。
ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。
这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源。
所以,不用进行close关闭。
字符编码:
编码:字符串变成字节数组。
解码:字节数组变成字符串。