1. JDK1.7前处理:
- 之前我们习惯了把异常抛出,而在实际开发中并不能这样处理,强烈建议使用try...catch...finally代码块,处理异常部分。
- JDK1.7之前示例代码:
import java.io.*;
public class FileCopy {
public static void main(String[] args) {
//创建文件对象并关联源文件
File srcFile = new File("H:/aaa.jpg");
//创建文件对象并关联目标文件
File destFile = new File("H:/bbb.jpg");
copyFile(srcFile,destFile);
}
public static void copyFile(File srcFile,File destFile) {
//声明字节输入输出流
FileInputStream fis = null;
FileOutputStream fos = null;
try {
//创建字节输入流对象关联源文件
fis = new FileInputStream(srcFile);
//创建字节输出流对象并关联目标文件
fos = new FileOutputStream(destFile);
//创建字节数组用于保存读取到的文件数据
byte[] b = new byte[1024];
//定义整型变量用于保存实际读取到的字节个数
int len=-1;
//循环读写数据
while ((len=fis.read(b))!=-1){
//利用fos将字节数组内容输出到目标文件中
fos.write(b,0,len);
}
}catch (Exception e){
}finally {
try{
//关闭流释放资源
if(fis != null)
fis.close();
}catch (Exception e){
e.printStackTrace();
}
try{
if(fos != null)
fos.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
2. JDK1.7之后处理异常方式:
JDK1.7之后处理异常的正确姿势(小括号中会帮我们处理关闭流的动作,不需要我们手动处理) try(创建流的代码){ }catch(异常类名 变量名){ } 小括号中只能放创建流的代码,调用流方法的代码不能放在小括号中
import java.io.*;
public class FileCopy {
public static void main(String[] args) {
//创建文件对象并关联源文件
File srcFile = new File("H:/aaa.jpg");
//创建文件对象并关联目标文件
File destFile = new File("H:/bbb.jpg");
copyFile(srcFile, destFile);
}
public static void copyFile(File srcFile, File destFile) {
try (//创建字节输入流对象关联源文件
FileInputStream fis = new FileInputStream(srcFile);
//创建字节输出流对象并关联目标文件
FileOutputStream fos = new FileOutputStream(destFile);)
{
//创建字节数组用于保存读取到的文件数据
byte[] b = new byte[1024];
//定义整型变量用于保存实际读取到的字节个数
int len = -1;
//循环读写数据
while ((len = fis.read(b)) != -1) {
//利用fos将字节数组内容输出到目标文件中
fos.write(b, 0, len);
}
} catch (Exception e) {
}
}
}
3. JDK1.9之后处理异常的方式:
JDK1.9之后处理异常的方式:(同样小括号中会帮我们处理关闭流的动作,不需要我们手动处理) try(流对象1;流对象2){ }catch(异常类名 变量名){ }
JDK1.7之后和JDK1.9之后注意事项:
- 同样小括号中会帮我们处理关闭流的动作,不需要我们手动处理
- 作用域不同:JDK1.7之后创建的流对象是放在小括号里面,JDK1.9之后创建的流对象是放在小括号外面,只需要传两个变量名过去小括号,作用域更大,但是JDK1.9需要作声明(...throws Exception...),否则会报错。
import java.io.*;
public class FileCopy {
public static void main(String[] args) throws FileNotFoundException {
//创建文件对象并关联源文件
File srcFile = new File("H:/aaa.jpg");
//创建文件对象并关联目标文件
File destFile = new File("H:/bbb.jpg");
copyFile(srcFile, destFile);
}
public static void copyFile(File srcFile, File destFile) throws FileNotFoundException {
//创建字节输入流对象关联源文件
FileInputStream fis = new FileInputStream(srcFile);
//创建字节输出流对象并关联目标文件
FileOutputStream fos = new FileOutputStream(destFile);
try (fis;fos) {
//创建字节数组用于保存读取到的文件数据
byte[] b = new byte[1024];
//定义整型变量用于保存实际读取到的字节个数
int len = -1;
//循环读写数据
while ((len = fis.read(b)) != -1) {
//利用fos将字节数组内容输出到目标文件中
fos.write(b, 0, len);
}
} catch (Exception e) {
}
}
}
Properties属性集:
- Properties类概述:
- 实现了Map接口,继承Hashtable,也是一个双列集合。
- 也是用来存储键值对数据,键和值默认是字符串类型,不需要指定类型了。
- 有和流技术相结合的方法:可以直接将集合中的数据保存到文件中/也可以直接从文件中读取数据到文件中
- 属性文件要求:
- 命名要求:xxx.properties
- 每一个键值对占据一行,格式:键=值
- 文件中可以使用注释的,注释是以#开头
- Properties集合常用方法
- Object setProperty(String key,String value)
- 添加键值对
- 如果键存在,则使用新值替换旧值,返回旧值
- 如果键不存在,则返回null
- String getProperty(String key)
- 根据键获得值,返回键对应的值
- 键不存在返回null
- set<String> stringPropertyNames():获得键集合
- void store(OutputStream out,String comments)
- 将集合中的数据保存到流关联的目标文件中
- comments:说明文字,一般给null即可
- void load(InputStream in)
- 从流关联的目标文件中加载数据到集合中
- 示例1:Properties集合常用方法
import java.util.Properties;
import java.util.Set;
/*
Properties集合常用方法
*/
public class PropertiesDemo01 {
public static void main(String[] args) {
//创建属性集合对象
Properties prop = new Properties();
//添加键值对
Object o = prop.setProperty("name", "马云");
Object o1 = prop.setProperty("name", "马化腾");
Object o2 = prop.setProperty("gender", "男");
Object age = prop.setProperty("age", "18");
System.out.println(o);//null
System.out.println(o1);//马云(新值替换旧值,马化腾替换马云,返回旧值,返回马云)
System.out.println(o2);//null
System.out.println(age);//null
System.out.println(prop);//{gender=男, name=马化腾, age=18}
//根据键获得值
System.out.println(prop.getProperty("name"));//马化腾
System.out.println("------------------------------");
//获得键集合
Set<String> names = prop.stringPropertyNames();
for (String name:names){
System.out.println(name+"="+prop.getProperty(name));
}
/*
gender=男
name=马化腾
age=18
*/
}
}
- 示例2:与流技术相结合的方法演示
import java.io.FileOutputStream;
import java.util.Properties;
/*
Properties集合方法:保存集合数据到文件中
*/
public class PropertiesDemo01 {
public static void main(String[] args) throws Exception{
//创建属性集合对象
Properties prop = new Properties();
//添加键值对
prop.setProperty("name", "马云");
prop.setProperty("gender", "男");
prop.setProperty("age", "18");
//创建字节输出流对象并关联目标文件
FileOutputStream fos = new FileOutputStream("teach.properties");
prop.store(fos,"this is teacher");
//关闭流
fos.close();
}
}
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
/*
Properties集合方法:从文件中读取数据到Properties集合中
*/
public class PropertiesDemo01 {
public static void main(String[] args) throws Exception{
//创建属性集合对象
Properties prop = new Properties();//{}
System.out.println(prop);
//创建字节输入流对象并关联目标文件
FileInputStream fis = new FileInputStream("teach.properties");
prop.load(fis);
//关闭流
fis.close();
System.out.println(prop);//{gender=男, name=马云, age=18}
}
}
IO流小结:
- IO流分类
字节流:以字节为单位读写数据
* 字节输入流:InputStream 所有字节输入流的父类
* 字节输出流:OutputStream 所有字节输出流的父类
字符流:以字符为单位读写数据
* 字符输入流:Reader 所有字符输入流的父类
* 字符输出流:Writer 所有字符输出流的父类
- 如何判断流是字节流还是字符流:
* 如果是以Stream结尾的流,就是字节流,否则都是字符流。
- IO流的使用步骤:
* 创建流关联目标文件
* 调用流的write或read方法读写数据
* 调用流的close方法关闭流释放资源
- 字节流和字符流的区别:
* 字节流:可以操作任意类型的文件
* 字符流:只能用来操作文本文件
- 字节流和字符流的选择:
* 如果明确清楚要操作的文件类型是文本文件,则强烈推荐使用字符流
* 如果不清楚要操作的文件类型是什么类型,则只能选择字节流。