本篇博客主要讲解I/O流,用表格简单总结:
一:File
1.1 File:文件和目录(文件夹)路径名的抽象表示形式。
1.2 File的构造方法:
File(String pathname):把一个路径名称封装成File对象
File(String parent, String child):把一个父路径和一个子路径封装成一个File对象
File(File parent, String child):把一个父路径File对象和一个子路径封装成一个File对象
1.3 创建功能:
A:创建文件
public boolean createNewFile():如果文件不存在,就创建。否则,不创建。
B:创建目录
public boolean mkdir():如果目录不存在,就创建。否则,不创建。
public boolean mkdirs():如果目录不存在,就创建。否则,不创建。
即使父目录不存在,也可以连父目录一起创建。
1.4 删除功能:
public boolean delete():既可以删除文件,又可以删除目录。
1.5 判断功能
public boolean isDirectory():是否是目录
public boolean isFile():是否是文件
public boolean exists():是否存在
public boolean canRead():是否可读
public boolean canWrite():是否可写
public boolean isHidden():是否隐藏
1.6获取功能
public String getAbsolutePath():获取绝对路径
public String getPath():获取相对路径
public String getName():获取名称
二:字节流及字节高效流
2.1 I/O流的分类
IO流分类:
流向:
输入流
输出流
数据类型:
字节流
字节输入流
字节输出流
字符流
字符输入流
字符输出流
注意:一般我们在讨论IO的分类时,默认是按照数据类型分的。
字节流:
* 字节输入流
InputStream(抽象类)
* 字节输出流
OutputStream(抽象类)
* 字符流:
* 字符输入流
Reader
* 字符输出流
Writer
2.2 FileOutputStream
A:构造方法:
FileOutputStream(File file)
FileOutputStream(String name)
FileOutputStream fos = new FileOutputStream("fos.txt");//创建a.txt文件
B:写数据的方法:
write(byte[] b)
write(int b) :一次写一个字节
write(byte[] b, int off, int len) :一次写一个字节数组的一部分。
fos.write("java".getBytes());
2.3 FileInputStream
字节流具体操作步骤:
A:创建字节输入流对象
FileInputStream fis = new FileInputStream("a.txt");
B:调用方法读取数据
一次读取一个字节:read() -- 测试读取不到内容的时候的返回值(并且用循环改进)
C:释放资源
fis.close
* 练习:
* A:把a.txt的内容复制到b.txt中
2.4 字节缓冲区流(也叫高效流):
BufferedInputStream(read() 一次读取一个字节, public int read(byte[] b):返回实际读取长度,数据被读取到数组中。)
BufferedOutputStream(write(byte[] b))
流:
低级流: 基本的流,可以直接操作文件。
高级流:是操作基本流的流。
2.5自己可以试一下
* 字节流复制文件(视频文件,并测试所用时间):
* A:基本字节流一次读写一个字节
* B:基本字节流一次读写一个字节数组
* C:高效字节流一次读写一个字节
* D:高效字节流一次读写一个字节数组
提示: 获取时间的方法:System.currentTimeMillis()
public class Test {
public static void main(String[] args) throws IOException {
/*
* * 字节流复制文件(视频文件,并测试所用时间):
* A:基本字节流一次读写一个字节
* B:基本字节流一次读写一个字节数组
* C:高效字节流一次读写一个字节
* D:高效字节流一次读写一个字节数组
* */
long start = System.currentTimeMillis();
//method1(); //277
//method2(); //26
//method3(); //169
method4(); //30
long end = System.currentTimeMillis();
long time = end-start;
System.out.println(time);
}
//高效字节流一次读写一个字节数组
private static void method4() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("H:\\我的\\12\\a.doc"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aa.doc"));
int len;
byte[] bys = new byte[1024];
while((len=bis.read(bys))!=-1){
bos.write(bys);
}bos.close();
bis.close();
}
//高效字节流一次读写一个字节
private static void method3() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("H:\\我的\\12\\a.doc"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aa.doc"));
int len;
while((len=bis.read())!=-1){
bos.write(len);
}
bos.close();
bis.close();
}
//基本字节流一次读写一个字节数组
private static void method2() throws IOException {
FileInputStream fis = new FileInputStream("H:\\我的\\12\\a.doc");
FileOutputStream fos = new FileOutputStream("aa.doc");
int len;
byte[] bys = new byte[1024];
while((len = fis.read(bys))!=-1){
fos.write(bys);
}
fos.close();
fis.close();
}
//基本字节流一次读写一个字节
private static void method1() throws IOException {
FileInputStream fis = new FileInputStream("H:\\我的\\12\\a.doc");
FileOutputStream fos = new FileOutputStream("aa.doc");
int len;
while((len=fis.read())!=-1){
fos.write(len);
}
fos.close();
fis.close();}
}
三:字符流 3.1 * OutputStreamWriter:把字节输出流转换为字符输出流 * InputStreamReader:把字节输入流转换为字符输入流 3.2 转换流 写入数据,把字节输出流转换为字符输出流(不指定码表)OutputStreamWriter osw = new OutputStreamWriter(new
FileOutputStream("osw.txt"));把字节输出流转换为字符输出流(指定码表)OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "GBK");OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "UTF-8"); 读取数据, 把字节输入流转换为字符输入流(不指定码表)InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"));把字节输入流转换为字符输入流(指定码表)InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"), "GBK");总结:我们一般创建字符输入或者输出流一般情况下使用系统默认的码表就可以, 如果来来回回需要指定码表的话,就显得非常的麻烦了 3.3 (将以上创建方式继续简化)* 如果采用刚才的方式,创建对象写起来比较复杂。* InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));* OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"));* 为了简化这种操作,java就针对这两个转换的字符流提供其子类。* FileReader* FileWriterA 构造方法: FileWriter(File file) FileWriter(String fileName) FileReader(File file) FileReader(String fileName)B 成员方法:
1 写数据方法:
一次写一个字符 write(int c)
一次写一个字符数组write(char[] cbuf)
一次写一个字符数组的一部分write(char[] cbuf, int off,int len)
一次写一个字符串write(String str)
一次写一个字符串的一部分write(String str,int off,int len)
2 flush()和close()的区别? (1):flush
刷新缓冲区,流对象可以继续 (2):close
先刷新缓冲区,再关闭流对象。流对象不可以继续使用了。3.4 字符输入流操作步骤 A:创建字符输入流对象FileReader fr = new FileReader("a.txt"); B:读取数据并显示在控制台(1):一次读取一个字符
int ch;
while ((ch = fr.read()) != -1) {
System.out.print((char) ch);
}
(2):一次读取一个字符数组 char[] chs = new char[1024];
int len;
while ((len = fr.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
C:释放资源fr.close();
注意:字符流输入输出流复制的文件是有要求的,简单来说只要是记事本打开文件的内容你能够看得懂,就可以用字符流来进行复制,否则不行
具体原因:像复制MP3或者一些视频文件的时候,如果他的字节个数不是偶数的话,就会造成文件的缺损,因为一个字符等于两个字节
3.5 高效流:(重要)
A: BufferedReader:字符缓冲输入流
构造:BufferedReader(Reader in)
特殊方法:public String readLine():包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
B: BufferedWriter:字符缓冲输出流
构造:BufferedWriter(Writer out)
特殊方法:public void newLine():会根据系统来确定写入不同的换行符
最终练习复制文本文件:
基本字符流一次读写一个字符
基本字符流一次读写一个字符数组
高效字符流一次读写一个字符
高效字符流一次读写一个字符数组
package com.edu_05;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test01 {
public static void main(String[] args) throws IOException {
/*
* 基本字符流一次读写一个字符
* 基本字符流一次读写一个字符数组
* 高效字符流一次读写一个字符
* 高效字符流一次读写一个字符数组
* */
method1();//高效字符流一次读写一个字符
method2();//高效字符流一次读写一个字符数组
method3();//基本字符流一次读写一个字符
method4();//基本字符流一次读写一个字符数组
}
private static void method4() throws IOException {
FileReader fr = new FileReader("b.txt");
FileWriter fw = new FileWriter("bb.txt");
int num;
char[] chs = new char[1024];
while((num=fr.read(chs))!=-1){
fw.write(chs);
}
fw.close();
fr.close();
}
private static void method3() throws IOException {
FileReader fr = new FileReader("b.txt");
FileWriter fw = new FileWriter("bb.txt");
int num;
while((num=fr.read())!=-1){
fw.write(num);
}
fw.close();
fr.close();
}
private static void method2() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("b.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("bb.txt"));
int num;
char[] chs = new char[1024];
while((num=br.read(chs))!=-1){
bw.write(chs);
}
bw.close();
br.close();
}
private static void method1() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("b.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("c.txt"));
int num;
while((num=br.read())!=-1){
bw.write(num);
}
br.close();
bw.close();
}
}
四:设计模式(了解)
A:设计模式概述
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性以及代码的结构更加清晰.
B:设计模式分类
创建型模式(创建对象的): 单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
行为型模式(对象的功能): 适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
结构型模式(对象的组成): 模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、
解释器模式、状态模式、策略模式、职责链模式、访问者模式。
单例设计模式(掌握)
A:单例设计思想
保证类在内存中只有一个对象
B:如何实现类在内存中只有一个对象呢?
构造私有
本身提供一个对象
通过公共的方法让外界访问
C:案例演示: 单例模式之饿汉式
工厂设计模式(掌握)
A:简单工厂模式概述:又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
B:优点:使用静态工厂模式的优点是实现责任的分割,该模式的核心是工厂类,工厂类含有必要的选择逻辑,可以决定什么时候创建哪一个产品的实例,
而客户端则免去直接创建产品的责任,而仅仅是消费产品。也就是说静态工厂模式在不改变客户端代码的情况可以动态的增加产品。明确了类的职责
C:缺点这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护。
(抽象工厂模式的概述和使用)(理解)
A:工厂方法模式概述
工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
B:优点
客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
C:缺点: 需要额外的编写代码,增加了工作量。