稳稳当当学java之文件和IO二(19)

tech2022-10-19  103

第二十一章 文件和IO二

1.作业回顾

1,编写程序,在E盘创建一个目录test,再创建一个子目录abc,在abc中创建一个文件test.txt,使用输出流将往test.txt中写一个字符串,然后再使用输入流,将test.txt中的文本读到程序中。

import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Day20HomeWork { public static void main(String[] args) { FileWriter fw = null; try { fw = new FileWriter("C:/test/abc/test.txt"); fw.write("我爱你中国!"); } catch (IOException e) { e.printStackTrace(); }finally { try { fw.flush(); } catch (IOException e) { e.printStackTrace(); } try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } FileReader fr = null; try { fr = new FileReader("C:/test/abc/test.txt"); int c = 0;//保存读到的字符 while(-1 != (c = ( fr.read() ))) System.out.println((char)c); } catch (IOException e) { e.printStackTrace(); }finally { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }

2,编写程序,在控制台输入源文件路径和目标文件路径,实现任意文件的复制。

import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Scanner; public class Day20HomeWork2 { public static void main(String[] args) { Scanner s = new Scanner(System.in); System.out.println("请输入源文件路径"); String src = s.nextLine(); System.out.println("请输入目标文件路径"); String dest = s.nextLine(); File srcFile = new File(src); File destFile = new File(dest); if (!srcFile.exists()) { System.out.println("源文件不存在"); }else { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); byte[] bs = new byte[256]; int len = 0; while(-1 != ( len = fis.read()) ) { fos.write(bs, 0, len); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { fos.flush(); } catch (IOException e) { e.printStackTrace(); } try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }

2.节点流和过滤流

2.1节点流和过滤流介绍

直接和数据源(文件,内存块,网络)相连接的流是节点流,否则就是过滤流。

过滤流相当于 在节点流上加了一个流。

节点流和过滤流示意图:

节点流:

FileReader:以字符读文件

FileWriter:以字符写文件

FileInputStream:以字节读文件

FileOutputStream: 以字节写文件

CharArrayReader:以字符读字符数组

CharArrayWriter:以字符写字符数组

StringReader:以字符读字符串

StringWriter:以字符写字符串

ByteArrayInputStream:以字节读字节数组

ByteArrayOutputStream:以字节写字节数组

过滤流:

BufferedReader:以字符读缓冲区

BufferedWriter:以字符写缓冲区

BufferedInputStream:以字节读缓冲区

BufferedOutputStream:以字节写缓冲区

InputStreamReader:以字节输入流转换为字符输入流

OutputStreamWriter:以字符输出流转换为字节输出流

ObjectInputStream:以字节读对象

ObjectOutputStream:以字节写对象

import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class Day2103 { public static void main(String[] args) { FileReader fr = null; BufferedReader br = null; try { fr = new FileReader("C:/test/abc/test.txt"); //将fr包装成一个缓冲过滤流 //缓冲过滤流内部有一个缓冲区,可以提高IO效率 //装饰者模式 br = new BufferedReader(fr); int c = 0; while(-1 != ( c = br.read() )) { System.out.print((char)c);//中国你好 } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { //只需要关闭最外层的流 //外层流关闭时会关闭内层流 try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; public class Day2104 { public static void main(String[] args) { BufferedWriter bw = null; try { bw = new BufferedWriter(new FileWriter("C:/test/abc/test.txt")); bw.write("我爱你中国"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { bw.flush(); } catch (IOException e) { e.printStackTrace(); } try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } }

3.以指定编码读写文件

import java.nio.charset.Charset; public class Day2105 { public static void main(String[] args) { //获取默认字符集 Charset charset = Charset.defaultCharset(); System.out.println(charset);//UTF-8 } }

3.1使用GBK读取文件

import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; public class Day2106 { public static void main(String[] args) { FileInputStream fis = null; //过滤流,可以包装一个字节流,获得一个字符流,采用指定的编码方式进行转换 InputStreamReader isr = null; BufferedReader br = null; try { fis = new FileInputStream("C:/test/abc/test.txt"); //将字节流以GBK编码转换为字符流 isr = new InputStreamReader(fis, "GBK"); br = new BufferedReader(isr); String str = null; while(null != (str = br.readLine())) { System.out.println(str); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } }

3.2使用UTF-8写入文件

import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; public class Day2107 { public static void main(String[] args) { FileOutputStream fos = null; OutputStreamWriter osw = null; BufferedWriter bw = null; try { fos = new FileOutputStream("C:/test/abc/test.txt"); osw = new OutputStreamWriter(fos, "UTF-8"); bw = new BufferedWriter(osw); bw.write("哆啦A梦"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { bw.flush(); } catch (IOException e) { e.printStackTrace(); } try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } }

4.对象的序列化和反序列化一

对象的序列化是将对象保存到外部存储(文件,数据库,网络)。

对象的反序列化是将外部存储(文件,数据库,网络)转换为对象。

为了将对象进行序列化和反序列化,必须实现Serializable接口。Serializable接口是一个标志接口,并没有方法。

4.1将对象保存在外部存储

import java.io.Serializable; //为了进行序列化和反序列化,必须实现Serializable接口 public class Student implements Serializable{ private String name; private int age; public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } } import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class Day2108 { public static void main(String[] args) { Student s1 = new Student("张三", 20); FileOutputStream fos = null; ObjectOutputStream oos = null; try { fos = new FileOutputStream("C:/test/abc/Student.ser"); //过滤流,将一个对象写到输出流中 oos = new ObjectOutputStream(fos); //将对象s1写到输出流中 oos.writeObject(s1); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { oos.flush(); } catch (IOException e) { e.printStackTrace(); } try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } }

4.2将外部存储转换为对象

import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.ObjectInputStream; public class Day2109 { public static void main(String[] args) { FileInputStream fis = null; ObjectInputStream ois = null; try { fis = new FileInputStream("C:/test/abc/Student.ser"); //过滤流,可以从输入流中取读对象 ois = new ObjectInputStream(fis); //读取到的对象实际是Student类型的对象,因此可以进行强制类型转换 Student s = (Student) ois.readObject(); System.out.println(s.getName());//张三 System.out.println(s.getAge()); //20 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }finally { try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } }

5.对象的序列化和反序列化二

5.1 transient关键字

如果不想序列化某个字段,可以使用transient关键字

import java.io.Serializable; //为了进行序列化和反序列化,必须实现Serializable接口 public class Student implements Serializable{ private String name; //transient表示不对此字段进行序列化和反序列化 //瞬时——不必持久化 private transient int age; public Student(String name, int age) { super(); this.name = name; this.age = age; //反序列化不会调用构造器 System.out.println("Student构造器"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }

5.2 序列化链

序列化时,如果一个对象的字段也是对象,那么这个字段也会序列化。

注意:所有需要序列化的对象都必须实现Serializable接口。

import java.io.Serializable; //为了进行序列化和反序列化,必须实现Serializable接口 public class Student implements Serializable{ private String name; //transient表示不对此字段进行序列化和反序列化 //瞬时——不必持久化 private transient int age; public Student(String name, int age) { super(); this.name = name; this.age = age; //反序列化不会调用构造器 System.out.println("Student构造器"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } public void setTeacher(Teacher t1) { } } import java.io.Serializable; public class Teacher implements Serializable { private String name; private int age; private String school; public Teacher(String name, int age, String school) { super(); this.name = name; this.age = age; this.school = school; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } @Override public String toString() { return "Teacher [name=" + name + ", age=" + age + ", school=" + school + "]"; } } import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class Day2108 { public static void main(String[] args) { Student s1 = new Student("张三", 20); Teacher t1 = new Teacher("张三丰", 200, "清华"); s1.setTeacher(t1); FileOutputStream fos = null; ObjectOutputStream oos = null; try { fos = new FileOutputStream("C:/test/abc/Student.ser"); //过滤流,将一个对象写到输出流中 oos = new ObjectOutputStream(fos); //将对象s1写到输出流中 oos.writeObject(s1); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { oos.flush(); } catch (IOException e) { e.printStackTrace(); } try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } } import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.ObjectInputStream; public class Day2109 { public static void main(String[] args) { FileInputStream fis = null; ObjectInputStream ois = null; try { fis = new FileInputStream("C:/test/abc/Student.ser"); //过滤流,可以从输入流中取读对象 ois = new ObjectInputStream(fis); //读取到的对象实际是Student类型的对象,因此可以进行强制类型转换 Student s = (Student) ois.readObject(); System.out.println(s.getName());//张三 System.out.println(s.getAge()); //20 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }finally { try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } }

6.Properties文件的使用

java.util.Properties类代表一个java配置文件。

java配置文件以.properties结尾,可以将配置参数。

如数据库连接地址放入到配置文件中,而不使用硬编码。

import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class Day2110 { public static void main(String[] args) { //props代表了一个配置文件 Properties props = new Properties(); //将配置文件的信息加载到props对象中 //Day2110.class是一个类对象 //java中的每一个类一旦加载到jvm中,就会产生一个类对象 //类对象描述了类的信息(有什么方法,有什么属性) //类对象有一个方法getResourceAsStream可以从classpath路径下加载文件 //java从classpath下加载类 //每个类只被加载一次,每个类只有一个类对象 InputStream is = null; //将流中的数据加载到props对象中 is = Day2110.class.getResourceAsStream("/day21/db.properties"); try { props.load(is); //props.getProperty方法通过key得到value System.out.println(props.getProperty("username"));//name System.out.println(props.getProperty("password"));//1234 } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } }

7.练习

以指定的编码读取文件内容,并将读到的内容以指定的编码写文件,两种编码都配置到properties文件中。

最新回复(0)