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();
}
try-with-resource
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方法。一般使用在想要自定义想要序列化属性的时候。