------- android培训、java培训、期待与您交流! ----------
IO流
IO流:即InputOutput的缩写。
小知识点
输入流和输出流相对于内存设备而言.
将外设中的数据读取到内存中:输入
将内存的数写入到外设中:输出。
IO流的常用基类:
1)字节流:InputStream和OutputStream
2)字符流:Reader和Writer
字符流
字符流的由来
其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表。获取对应的文字。
在对这个文字进行操作。简单说:字节流+编码表
原理图
字符流的读写
写入字符流过程
1、创建一个可以往文件中写入字符数据的字符输出流对象。
2、既然是往一个文件中写入文字数据,那么在创建对象时,就必须明确该文件(用于存储数据的目的地)。
3、如果文件不存在,则会自动创建。
4、如果文件存在,则会被覆盖。
5、如果构造函数中加入true,可以实现对文件进行续写!
应用事例
//需求:将一些文字存储到硬盘一个文件中。
public class FileWriterDemo {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("demo.txt",true);
// 调用Writer对象中的write(string)方法,写入数据。
// 其实数据写入到临时存储缓冲区中。
fw.write("abcde"+LINE_SEPARATOR+"hahaha");
// fw.write("xixi");
// 进行刷新,将数据直接写到目的地中。
// fw.flush();
// 关闭流,关闭资源。在关闭前会先调用flush刷新缓冲中的数据到目的地。
fw.close();
// fw.write("haha");//关闭后无法写入,如果继续写会报错: java.io.IOException: Stream closed
}
}
2、读取字符流步骤
1)创建一个文件读取流对象,和指定名称的文件相关联。要保证该文件已经存在,若不存在,将会发生异常FileNotFoundException。
2)调用读取流对象的read()方法。read():一次读一个字符,且会继续往下读。
第一种方式:读取单个字符。第二种方式:通过字符数组进行读取。
3)读取后要调用close方法将流资源关闭。
示例:
//需求:读取一个文本文件。将读取到的字符打印到控制台.
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
//1,创建读取字符数据的流对象。
/*
* 在创建读取流对象时,必须要明确被读取的文件。一定要确定该文件是存在的。
* 用一个读取流关联一个已存在文件。
*/
FileReader fr = new FileReader("demo.txt");
int ch = 0;
while((ch=fr.read())!=-1){
System.out.println((char)ch);
}
fr.close();
}
}
字符流的缓冲区——BufferedReader和BufferedWriter
特点
缓冲区提高了流的读写效率,所以在缓冲区创建前,要先创建流对象。
缓冲技术原理:此对象中封装了数组,将数据存入,再一次性取出。
写入流缓冲区BufferedWriter的步骤:
1、创建一个字符写入流对象。
2、为了提高字符写入流效率。加入缓冲技术。只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可。
3、调用write方法写入数据到指定文件
4、其实关闭缓冲区,就是在关闭缓冲区中的流对象。
应用事例
public class BufferedWriterDemo {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("buf.txt");
//为了提高写入的效率。使用了字符流的缓冲区。
//创建了一个字符写入流的缓冲区对象,并和指定要被缓冲的流对象相关联
BufferedWriter bufw = new BufferedWriter(fw);
//使用缓冲区的写入方法将数据先写入到缓冲区中。
for(int x=1; x<=4; x++){
bufw.write("abcdef"+x);
bufw.newLine();
bufw.flush();
}
//使用缓冲区的刷新方法将数据刷目的地中。
// bufw.flush();
//关闭缓冲区。其实关闭的就是被缓冲的流对象。
bufw.close();
}
}
读取流缓冲区BufferedReader
步骤:
1、创建一个读取流对象和文件相关联
2、为了提高效率。加入缓冲技术。将字符读取流对象作为参数传递给缓冲区对象的构造函数。
3、调用该缓冲区提供的readLine方法一行一行读取,如果到达文件末尾,则返回null
4、关闭流资源
应用事例
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("buf.txt");
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((line=bufr.readLine())!=null){
System.out.println(line);
}
bufr.close();
}
public static void demo() throws FileNotFoundException, IOException {
FileReader fr = new FileReader("buf.txt");
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
fr.close();
}
}
原理图
LineNumberReader
在BufferedReader中有个直接的子类LineNumberReader,其中有特有的方法获取和设置行号:
setLineNumber();设置初始行号
getLineNumber();获取行号
应用事例
public class LineNumberReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("IO流_2.txt");
LineNumberReader lnr = new LineNumberReader(fr);
String line = null;
lnr.setLineNumber(100);
while((line=lnr.readLine())!=null){
System.out.println(lnr.getLineNumber()+":"+line);
}
lnr.close();
}
}
装饰设计模式
由来:对已有对象进行功能增强时,需要自定义一个类,那么自定义的该类称之为装饰类。
装饰和继承的区别:
1、装饰模式比继承要灵活。避免了继承体系的臃肿,且降低了类与类之间的关系。
2、装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能,所以装饰类和被装饰的类通常都是属于一个体系。
3、从继承结构转为组合结构。
示例:创建自定义缓冲区
public class MyBufferedReader extends Reader {
private Reader r;
//定义一个数组作为缓冲区。
private char[] buf = new char[1024];
//定义一个指针用于操作这个数组中的元素。当操作到最后一个元素后,指针应该归零。
private int pos = 0;
//定义一个计数器用于记录缓冲区中的数据个数。 当该数据减到0,就从源中继续获取数据到缓冲区中。
private int count = 0;
MyBufferedReader(Reader r){
this.r = r;
}
public int myRead() throws IOException{
if(count==0){
count = r.read(buf);
pos = 0;
}
if(count<0)
return -1;
char ch = buf[pos++];
count--;
return ch;
}
public String myReadLine() throws IOException{
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch = myRead())!=-1){
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
//将从缓冲区中读到的字符,存储到缓存行数据的缓冲区中。
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
public void myClose() throws IOException {
r.close();
}
public int read(char[] cbuf, int off, int len) throws IOException {
return 0;
}
public void close() throws IOException {
}
}
示例:应用自定义缓冲区
public class MyBufferedReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("buf.txt");
MyBufferedReader bufr = new MyBufferedReader(fr);
String line = null;
while((line=bufr.myReadLine())!=null){
System.out.println(line);
}
bufr.myClose();
Collections.reverseOrder();
HashMap map = null;
map.values();
}
}