IO资源的处理
JDK7前处理
之前的入门练习,我们一直把异常抛出,而实际开发中并不能这样处理,建议使用try...catch...finally
代码块,处理异常部分
public class Test1_JDK7前处理 {
public static void main(String[] args) {
// jdk7之前IO异常处理:try...catch...finally
FileInputStream fis = null;
FileOutputStream fos = null;
try {
// 1.创建字节输入流对象,关联数据源文件路径
fis = new FileInputStream("day11\\aaa\\hb.jpg");
// 2.创建字节输出流对象,关联目的地文件路径
fos = new FileOutputStream("day11\\aaa\\hbCopy1.jpg");
// 3.定义一个byte数组,用来存储读取到的字节数据
byte[] bytes = new byte[8192];
// 3.定义一个int变量,用来存储读取到的字节个数
int len;
// 4.循环读数据
while ((len = fis.read(bytes)) != -1) {
// 5.在循环中,写数据
fos.write(bytes, 0, len);
}
} catch (IOException e) {
System.out.println("发生了异常:" + e.getMessage());
} finally {
// 6.关闭流,释放资源
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
JDK7的处理
可以使用JDK7优化后的try-with-resource
语句,该语句确保了每个资源在语句结束时自动关闭。所谓的资源(resource)是指在程序完成后,必须关闭的对象。
try (创建流对象语句,如果多个,使用';'隔开) {
// 读写数据
} catch (IOException e) {
e.printStackTrace();
}
public class Test2_JDK7的处理 {
public static void main(String[] args) {
// jdk7的IO异常处理: try...with.resource
try (
// 1.创建字节输入流对象,关联数据源文件路径
FileInputStream fis = new FileInputStream("day11\\aaa\\hb.jpg");
// 2.创建字节输出流对象,关联目的地文件路径
FileOutputStream fos = new FileOutputStream("day11\\aaa\\hbCopy2.jpg");
) {
// 3.定义一个byte数组,用来存储读取到的字节数据
byte[] bytes = new byte[8192];
// 3.定义一个int变量,用来存储读取到的字节个数
int len;
// 4.循环读数据
while ((len = fis.read(bytes)) != -1) {
// 5.在循环中,写数据
fos.write(bytes, 0, len);
}
// 6.关闭流,释放资源
//fos.close();
//fis.close();
} catch (Exception e) {
System.out.println("发生了异常:" + e.getMessage());
}
}
}
属性集
-
Properties类继承Hashtable,而Hashtable实现了Map接口,所以Properties本质其实就是一个Map集合,可以使用Map接口中的所有方法,但一般不把Properties当成Map集合使用
-
Properties也是一个属性集,可以用来加载文件中的数据(键值对的形式存储), 并且Properties属性集中每个键及其对应值都是一个字符串。
-
构造方法
-
public Properties()创建一个空的属性集对象
-
-
public Object setProperty(String key, String value) 保存一对属性。
public String getProperty(String key) 使用此属性列表中指定的键搜索属性值。
public Set<String> stringPropertyNames() 所有键的名称的集合。
缓冲流
-
字节缓冲流:
BufferedInputStream
,BufferedOutputStream
-
字符缓冲流:
BufferedReader
,BufferedWriter
字节缓冲流
-
BufferedInputStream类:
public BufferedInputStream(InputStream is);
-
BufferedOutputStream类:
public BufferedOutputStream(OutputStream os);
public class Test1_普通字节流一次读写一个字节拷贝文件 {
public static void main(String[] args) throws Exception{
// 0.拷贝开始时间
long start = System.currentTimeMillis();
// 1.创建字节输入流对象,关联数据源文件路径
FileInputStream fis = new FileInputStream("day11\\aaa\\jdk9.exe");
// 2.创建字节输出流对象,关联目的地文件路径
FileOutputStream fos = new FileOutputStream("day11\\aaa\\jdk9Copy1.exe");
// 3.定义一个int变量,用来存储读取到的字节数据
int b;
// 4.循环读
while ((b = fis.read()) != -1) {
// 5.写数据
fos.write(b);
}
// 6.关闭流,释放资源
fos.close();
fis.close();
// 7.拷贝开始时间
long end = System.currentTimeMillis();
System.out.println("总共花了:"+(end - start)+"毫秒");// 至少十几分钟
}
}
public class Test2_字节缓冲流一次读写一个字节拷贝文件 {
public static void main(String[] args) throws Exception{
// 0.拷贝开始时间
long start = System.currentTimeMillis();
// 1.创建字节缓冲输入流对象,关联数据源文件路径
FileInputStream fis = new FileInputStream("day11\\aaa\\jdk9.exe");
BufferedInputStream bis = new BufferedInputStream(fis);
// 2.创建字节缓冲输出流对象,关联目的地文件路径
FileOutputStream fos = new FileOutputStream("day11\\aaa\\jdk9Copy2.exe");
BufferedOutputStream bos = new BufferedOutputStream(fos);
// 3.定义一个int变量,用来存储读取到的字节数据
int b;
// 4.循环读
while ((b = bis.read()) != -1) {
// 5.写数据
bos.write(b);
}
// 6.关闭流,释放资源
bos.close();
bis.close();
// 7.拷贝开始时间
long end = System.currentTimeMillis();
System.out.println("总共花了:"+(end - start)+"毫秒");// 大概28秒
}
}
public class Test3_字节缓冲流一次读写一个字节数组拷贝文件 {
public static void main(String[] args) throws Exception{
// 0.拷贝开始时间
long start = System.currentTimeMillis();
// 1.创建字节缓冲输入流对象,关联数据源文件路径
FileInputStream fis = new FileInputStream("day11\\aaa\\jdk9.exe");
BufferedInputStream bis = new BufferedInputStream(fis);
// 2.创建字节缓冲输出流对象,关联目的地文件路径
FileOutputStream fos = new FileOutputStream("day11\\aaa\\jdk9Copy3.exe");
BufferedOutputStream bos = new BufferedOutputStream(fos);
// 3.定义一个int变量,用来存储读取到的字节数据
byte[] bys = new byte[8192];
// 3.定义一个int变量,用来存储读取到的字节个数
int len;
// 4.循环读
while ((len = bis.read(bys)) != -1) {
// 5.写数据
bos.write(bys,0,len);
}
// 6.关闭流,释放资源
bos.close();
bis.close();
// 7.拷贝开始时间
long end = System.currentTimeMillis();
System.out.println("总共花了:"+(end - start)+"毫秒");// 大概5秒
}
}
-
BufferedReader类:
public BufferedReader(Reader r);创建一个字符缓冲输入流对象
-
BufferedWriter类:
public BufferedWriter(Writer w);创建一个字符缓冲输出流对象
OutputStreamWriter类
-
概述: java.io.OutputStreamWriter类继承Writer类,所以也是字符输出流,可以用来写字符数据
-
作用:
-
1.可以将字节输出流转换为字符输出流
-
2.可以指定编码写数据
-
-
构造方法:
-
public OutputStreamWriter(OutputStream os);创建转换输出流对象,使用平台默认字符集
-
public OutputStreamWriter(OutputStream os,String charsetName);创建转换输出流对象,指定字符集
------>掌握,常用
-
-
ObjectOutputStream类
-
概述: java.io.ObjectOutputStream类继承OutputStream,所以是一个字节输出流,可以用来写出字节数据,并且可以写Java对象
-
构造方法
-
public ObjectOutputStream(OutputStream out);创建序列化流对象,传入字节输出流
-
-
序列化操作---->写对象到文件中,变成字节数据
-
public void wirteObject(Object obj);写一个对象(序列化操作)
-
-
注意: 被序列化的对象所属的类一定要实现Serializable接口(标记接口)
-
ObjectInputStream类
-
概述: java.io.ObjectInputStream类继承InputStream,所以是一个字节输入流,可以用来读字节数据,并且可以读Java对象
-
构造方法
-
public ObjectInputStream(InputStream in);创建反序列化流对象,传入字节输入流
-
-
反序列化操作
-
public Object readObject();重构一个对象
-
-
序列化和反序列化注意事项
序列化的注意事项
-
被序列化的对象所属的类一定要实现Serializable接口(标记接口)
-
被序列化的对象所有的属性也是要可以被序列化的
-
如果别序列化的对象的属性不想被序列化,那么该属性就需要使用transient关键字修饰,表示瞬态
-
打印流
- java.io.PrintStream类继承OutputStream,也是一个字节输出流,可以用来写出字节数据
-
构造方法:
-
public PrintStream(String fileName);创建一个打印流对象,通过参数关联目的地文件路径
-
-
成员方法:
-
public void print(任意类型);打印任意类型的数据到目的地文件中,打印完不换行
-
public void println(任意类型);打印任意类型的数据到目的地文件中,打印完换行
-
装饰模式遵循原则:
-
装饰类和被装饰类必须实现相同的接口
-
在装饰类中必须传入被装饰类的引用
-
在装饰类中对需要扩展的方法进行扩展
-
在装饰类中对不需要扩展的方法调用被装饰类中的同名方法
commons-io工具包