public static void main(String[] args) throws FileNotFoundException { /** * 打印流与缓存读取流,打印流用于打印字符。S * ystem.out的类型是PrintStream,字符输出(打印流)。 * 自己创建一个打印流。 */ //表示打印到c盘的c.txt文件。字符流。 PrintStream ps = new PrintStream("c://c.txt"); //可以调用打印流的方法 ps.println("任意字符串"); //表示打印到c盘的c.txt文件。字节流。 PrintWriter pw = new PrintWriter("c://c.txt"); //可以调用打印流的方法 pw.println("任意字符串"); //字符流与字节流最大的区别就是是否要刷新管道,字符流需要刷新管道。 //不刷新管道就看不到。 pw.flush(); }
public static void main(String[] args) { /** * 关闭资源的方法一: * 在try块里声明资源,在finally块里关闭资源, * 防止在try块里出现异常导致资源无法关闭。 * 但是这样会有一个问题,在finally块里要关闭资源 * 还会要写try...catch语句。 */ FileReader fr = null; try { fr = new FileReader("c://book.txt"); int c = fr.read(); System.out.println((char)c); } catch (IOException e) { e.printStackTrace(); } finally { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } }
public static void main(String[] args) { /** * 关闭资源的方法二: * 在try块里的小括号中声明资源(要完整的新建对象语句才行),资源会自动关闭。 * 能在try块的小括号中声明的资源其类或者继承的父类中必须实现Closeable接口或者AutoCloseable接口。 */ try (FileReader fr = new FileReader("c://book.txt")){ int c = fr.read(); System.out.println((char)c); } catch (IOException e) { e.printStackTrace(); } }
public static void main(String[] args) { /** * 自定义实现Closeable接口的类。 */ try (CloseDemo c = new CloseDemo()) { } catch (IOException e) { e.printStackTrace(); } } static class CloseDemo implements Closeable { @Override public void close() throws IOException { System.out.println("close方法被调用了"); } }
想要序列化的类要实现Serializable接口,类中不想实现序列化的属性添加transient修饰词,static修饰的属性也不会参与序列化。
public class Demo2 implements Serializable{ private transient String name; private int age; private List<String> family = new ArrayList<>(); public Demo2(String name, int age, List<String> family) { this.name = name; this.age = age; this.family = family; } @Override public String toString() { return "Demo2{" + "name='" + name + '\'' + ", age=" + age + ", family=" + family + '}'; } public static void main(String[] args) throws IOException, ClassNotFoundException { List<String> family = new ArrayList<>(); family.add("爸爸"); family.add("妈妈"); Demo2 demo = new Demo2("张三",30, family); System.out.println(demo); OutputStream os = new FileOutputStream("d://1.txt"); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(demo); os.close(); oos.close(); InputStream is = new FileInputStream("d://1.txt"); ObjectInputStream ois = new ObjectInputStream(is); Object o = ois.readObject(); is.close(); ois.close(); System.out.println(o); } }
或者在想要序列化的类中写私有方法writeObject与readObject,两个方法中序列化与反序列化的属性都要对应,当序列化或反序列化时,虚拟机会找到这两个方法运行方法内相应代码,在方法内写上要序列化的属性,该属性就会被序列化,没有写的属性就不会序列化。如果没有这两个方法,就会调用ObjectStreamClass中默认的这两个方法序列化属性。
public class Demo2 implements Serializable{ private String name; private int age; private List<String> family = new ArrayList<>(); public Demo2(String name, int age, List<String> family) { this.name = name; this.age = age; this.family = family; } @Override public String toString() { return "Demo2{" + "name='" + name + '\'' + ", age=" + age + ", family=" + family + '}'; } private void writeObject(ObjectOutputStream oos) throws IOException { System.out.println("writeObject方法被调用了。"); oos.writeObject(name); oos.writeObject(family); } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { System.out.println("readObject方法被调用了。"); name = (String) ois.readObject(); family = (List<String>) ois.readObject(); } private static void demo2Serializable(Demo2 demo2, String filePath) throws IOException { OutputStream os = new FileOutputStream(filePath); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(demo2); os.close(); oos.close(); } private static Object demo2DeSerializable(String filePath) throws IOException, ClassNotFoundException { InputStream is = new FileInputStream(filePath); ObjectInputStream ois = new ObjectInputStream(is); Object o = ois.readObject(); is.close(); ois.close(); return o; } public static void main(String[] args) { List<String> family = new ArrayList<>(); family.add("爸爸"); family.add("妈妈"); Demo2 demo = new Demo2("张三",30, family); System.out.println("原始数据:" + demo); String filePath = "d://1.txt"; try { demo2Serializable(demo, filePath); } catch (IOException e) { e.printStackTrace(); } try { Object o = demo2DeSerializable(filePath); System.out.println("反序列化后数据:" + o); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
还可以通过实现Externalizable接口(继承自Serializable接口)实现序列化与反序列化,要重写该接口中的两个方法,相当于writeObject与readObject方法。一般使用在想要自定义想要序列化属性的时候。