Java进阶11 IO流-功能流
一、字符缓冲流
字符缓冲流在源代码中内置了字符数组,可以提高读写效率
1、构造方法
方法 | 说明 |
---|
BufferedReader(new FileReader(文件路径)) | 对传入的字符输入流进行包装 |
BufferedWriter(new FileWriter(文件路径)) | 对传入的字符输出流进行包装 |
注意:缓冲流不具备读写功能,它们只是对普通的流对象进行包装,正真和文件建立关联的,还是普通流对象
1.1 字符缓冲流的使用
public class BufferedStreamDemo1 {/*1、字符缓冲流的基本使用*/public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new FileReader("day10\\A.txt"));
//单个读取int i;while((i=br.read())!=-1){System.out.println((char)i);}
//读取字符数组的一部分int len;char[] chs = new char[1024];while((len=br.read())!=-1){String s = new String(chs,0,len);System.out.println(s);}
br.close();
//字符缓冲输出流BufferedWriter bw = new BufferedWriter(new FileWriter("day10\\A.txt"));bw.write("写入数据......")bw.close();}
}
1.2 拷贝文件Demo
public class BufferedStreamDemo {/*字符缓冲流+自定义数组 拷贝文件*/public static void main(String[] args) throws IOException {//字符流只能拷贝纯文本文件BufferedReader br = new BufferedReader(new FileReader("day11\\FileReaderDemo1.java"));BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\copy.java"));
int len;char[] chs = new char[1024];while((len=br.read())!=-1){bw.write(chs,0,len);}br.close();bw.close();}
}
2、成员方法(特有)
2.1 BufferedReader
方法 | 说明 |
---|
public String readLine() | 一次性读取整行字符串,读取到末尾返回null |
2.2 BufferedWriter
方法 | 说明 |
---|
public void newLine() | 写出换行符(具有兼容性)兼容各个操作系统的换行符 |
2.3 特有方法使用Demo
public class BufferedStreamDemo2 {/*拷贝本项目中A.txt文件到本项目copy.txt;一整行一整行地拷贝*/public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new FileReader("day11\\A.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\copy.txt"));
String line;while((line=br.readLine())!=null){//readLine读不到换行符bw.write(line);//写出换行符bw.newLine();}br.close();bw.close();}
}
二、转换流
1、按照指定的字符编码读写操作
构造方法 | 说明 |
---|
InputStreamReader(InputStream in,String charsetName) | 按照指定的字符编码读取 |
OutputStreamWriter(OutputStream out,String charsetName) | 按照指定的字符编码写出 |
public class ChangeStreamDemo {/*转换流的使用Demo*/public static void main(String[] args) throws IOException {//使用GBK字符编码向路径D:\itheima\Resource\A.txt文件写入你好呀OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\itheima\\Rescouce\\A.txt"),"GBK");osw.write("你好呀");osw.close();
//使用gbk字符编码从路径D:\itheima\Resource\A.txt文件中读取字符InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\itheima\\Resource\\A.txt"),"gbk");//单个读取int i;while((i=isr.read())!=-1){System.out.print((char)i);}isr.close();}
}
2、将字节流转换为字符流进行操作
三、序列化流
可以在流中,以字节的形式直接读写对象
1、构造方法
方法 | 说明 |
---|
public ObjectInuputStream(InputStream in) | 对象输入流关联文件,关联方式使用字节输入流 |
public ObjectOutputStream(OutoutStream out) | 对象输出流关联文件,关联方式使用字节输出流 |
2、成员方法
方法 | 说明 |
---|
Object readObject() | 从流中读取对象(反序列化) |
void writeObject(Object obj) | 在流中将对象写出(序列化) |
3、方法使用案例
需求:现有3个学生对象,并将对象序列化到流中,随后完成反序列化操作
public class ObjectStreamDemo2 {public static void main(String[] args) throws IOException, ClassNotFoundException {readObject();
//用流读对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\obj.txt"));ArrayList<Student> stuList = (ArrayList<Student>) ois.readObject();System.out.println(stuList);ois.close();}
//将对象写入流private static void readObject() throws IOException {//为了一次读写三个学生对象,创建list集合存储ArrayList<Student> stu = new ArrayList<>();stu.add(new Student("张三",23));stu.add(new Student("李四",24));stu.add(new Student("王五",25));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\obj.txt"));oos.writeObject(stu);oos.close();}
}
注意事项
-
类需要实现Serializable接口才可以序列化
-
实现接口后,类就会自带一份序列版本号。序列化操作的时候,会将对象信息和版本号一并保存到文件,反序列化的时候,会拿着版本号和流中的版本号进行对比,不一致就会抛异常,起到提醒作用。为了避免这个问题,推荐手动写死serialVersionUID
在IDEA中设置快捷添加serialVersionUID的快捷键
-
-
如果类中的属性被transient进行修饰,将不会参与序列化操作
-
建议:对象的读写操作只进行一次
四、打印流
打印流可以实现方便、高效的打印数据到文件中去(打印什么数据就是什么数据)
1、PrintStream字节打印流(重点)
构造器 | 说明 |
---|
public PrintStream(OutputStream os) | 打印流直接通向字节输出流管道(想要追加时可在os对象的第二个参数位置打开append追加开关) |
public PrintStream(File f) | 打印流直接通向文件对象 |
public PrintStream(String filepath) | 打印流直接通向文件路径 |
成员方法 | 说明 |
---|
public void print\println(Xxx xxx) | 打印任意类型的数据出去 |
2、PrintWriter字符打印流(了解即可)
构造器 | 说明 |
---|
public PrintWriter(OutputStream os) | 打印流直接通向字节输出流管道 |
public PrintWriter(Writer w) | 打印流直接通向字符输出流管道 |
public PrintWriter(File f) | 打印流直接通向文件对象 |
public PrintWriter(String filepath) | 打印流直接通向文件路径 |
方法 | 说明 |
---|
public void print\println(Xxx xxx) | 打印任意类型的数据出去 |
五、Properties集合
1、Properties作为集合使用
构造器 | 说明 |
---|
Properties() | 创建一个没有默认值的空属性列表 |
方法 | 说明 |
---|
Object setProperty(String key,String value) | 添加(修改)一个键值对 |
String getPreperty(String key,String defaultValue) | 根据键获取值 |
Set<String> stringPropertyNames() | 获取集合中所有的键 |
public class PropertiesDemo1 {/*properties作为集合的使用*/public static void main(String[] args) {//1、创建集合容器(不需要指定泛型,键和值都是String类)Properties prop = new Properties();//2、添加数据到集合(类似于put方法,当key相同时,新value会覆盖旧value)prop.setProperty("username","admin");prop.setProperty("passward","123456");
//3、获取集合数据,根据键找值String username = prop.getProperty("username");String passward = prop.getProperty("passward");System.out.println(username+"----"+passward);
System.out.println("-------------------------------");
//4、类似Map集合中keySet方法,获取所有的键Set<String> keySet = prop.stringPropertyNames();//5、遍历集合+根据键找值拿到properties集合中的所有键值对for (String key : keySet) {System.out.println(key+"----"+prop.get(key));}}
}
2、Properties和IO有关的方法
方法 | 说明 |
---|
void load(InputStream inStream) | 从输入字节流读取属性列表(键和元素对) |
void load(Reader reader) | 从输入字符流读取属性列表(键和元素对) |
void store(OutputStream out,String comments) | 将此属性列表(键和元素对)写入此Properties表中,以适合于使用load(InputStream)方法的格式写入输出字符流 |
void store(Writer writer,String comments) | 将次属性列表(键和元素对)写入此Properties表中,以适合使用load(Reader)方法的格式写入输出字符流 |
public class PropertiesDemo2 {/*以字节输入输出流为例*/public static void main(String[] args) throws IOException {store();load();}
//读取方法private static void load() throws IOException {Properties prop = new Properties();FileInputStream fis = new FileInputStream("day11\\config.properties");//将读取到的内容存入prop集合prop.load(fis);System.out.println(prop);fis.close();
/**经常需要修改的值(如用户名密码、数据库连接密码等)写在配置文件里,到时候只要执行这个代码就能直接加载配置文件里的一些设置,免去了频繁修改代码的繁琐*/String username = prop.getProperty("username");String password = prop.getProperty("password");
System.out.println(username);System.out.println(password);}
//写入方法private static void store() throws IOException {Properties prop = new Properties();prop.setProperty("username","admin");prop.setProperty("password","123456");
FileOutputStream fos = new FileOutputStream("day11\\cpnfig.properties");
//第二个参数为备注内容,可传null,也可以传入字符串值prop.store(fos,"null");
fos.close();}
}