1、标准输入输出流:
测试代码1:
package test.com;
import java.util.Scanner;
public class TestInOut {
public static void main(String[] args) {
// 创建Scanner对象,读取标准输入流System.in
Scanner scanner = new Scanner(System.in);
// 提示用户输入文本
System.out.println("请输入文本:");
// 读取输入的一行文本
String input = scanner.nextLine();
// 使用System.out打印出输入的文本
System.out.println("您输入的是:" + input);
// 关闭scanner对象
scanner.close();
}
}
测试代码2:
package test.com;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class PrintStream {
// 使用PrintStream(通常是通过System.out)
public static void usePrintStream() {
// 直接使用System.out,它是PrintStream的一个实例
System.out.println("Using PrintStream to print to console:");
System.out.println("Hello, World! from PrintStream");
// 文件写入,通常使用PrintWriter或FileOutputStream结合其他包装类。
}
// 使用PrintWriter(写入文件到控制台)
public static void usePrintWriter() throws IOException {
// 写入控制台
try (PrintWriter pwConsole = new PrintWriter(System.out, true)) {
pwConsole.println("Using PrintWriter to print to console:");
pwConsole.println("Hello, World! from PrintWriter to console");
// try-with-resources,不需要显式调用close()。
}
// 写入文件
String filePath = "output.txt";
try (PrintWriter pwFile = new PrintWriter(new FileWriter(filePath), true)) {
pwFile.println("Using PrintWriter to write to file:");
pwFile.println("Hello, World! from PrintWriter to file");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
usePrintStream();
try {
usePrintWriter();
} catch (IOException e) {
e.printStackTrace();
}
// 可以在这添加更多逻辑验证文件是否已正确写入。
}
}
运行结果如下:
测试代码3:
package test.com;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
//PrintWriter(Writer out, boolean autoFlush)
//提供一个布尔参数 autoFlush 控制是否自动刷新输出缓冲区。
//out:是一个Writer类型的对象,PrintWriter 将通过这个对象写入数据。
//它可以是任何字符输出流,比如 FileWriter、StringWriter、OutputStreamWriter 包装的 OutputStream 等。
//autoFlush:是一个布尔值。
//如果设置为 true,则在调用 println(), printf(), 或 format() 方法时,将自动刷新输出缓冲区。
//每次调用这些方法后,缓冲区中的数据都会立即被写入到底层输出流中,而不是等待缓冲区满或显式调用 flush() 方法。
//如果设置为 false,则不会自动刷新缓冲区,除非显式调用 flush() 方法或在 PrintWriter 被关闭时自动发生。
public class PrintWriterExample {
public static void main(String[] args) {
try {
// 使用文件名创建PrintWriter,不会自动刷新
PrintWriter writer1 = new PrintWriter("example1.txt");
writer1.println("Hello, world!");
writer1.flush(); // 显式调用flush()刷新缓冲区
writer1.close();
// 使用FileWriter和自动刷新功能创建PrintWriter
FileWriter fw = new FileWriter("example2.txt");
PrintWriter writer2 = new PrintWriter(fw, true);
writer2.println("Auto-flushed line.");
// 由于autoFlush为true,所以不需要显式调用flush()
writer2.close(); // 关闭时也会刷新缓冲区
} catch (IOException e) {
e.printStackTrace();
}
}
}
2、对象序列化:
测试代码:
package test.com;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
//序列化的作用
//持久化:将对象的状态保存到磁盘上,即使程序终止运行,对象的状态信息也不会丢失。
//网络传输:将对象发送到网络上的另一个程序,实现远程方法调用(RMI)或分布式应用。
//注意事项
//Serializable接口:要序列化的类必须实现Serializable接口,该接口是一个标记接口,不包含任何方法。J
//ava虚拟机(JVM)通过这个接口判断一个类的对象是否可以序列化。
//transient关键字:如果一个类的字段被声明为transient,那么该字段将不会被序列化。可用于保护敏感信息或避免序列化不必要的对象。
//版本控制:如果序列化对象的类发生了变化(如增加了字段或修改了字段类型),那么反序列化时可能会遇到问题。
//可以通过在类中声明一个serialVersionUID避免这个问题,它用于确保序列化和反序列化的类版本兼容。
public class SerializeExample {
public static void main(String[] args) {
try (FileOutputStream fileOut = new FileOutputStream("employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
Employee emp = new Employee("John Doe", 50000, 1985);
out.writeObject(emp);
System.out.println("Serialized data is saved in employee.ser");
} catch (IOException i) {
i.printStackTrace();
}
}
}
class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int salary;
private transient int yearOfService; // transient关键字阻止该字段被序列化
public Employee(String name, int salary, int yearOfService) {
this.name = name;
this.salary = salary;
this.yearOfService = yearOfService;
}
//添加getter和setter方法以便访问这些字段
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public int getYearOfService() {
return yearOfService;
}
// 由于yearOfService是transient的,所以没有提供setYearOfService方法
// 在反序列化后,可能需要在某处重新计算或设置这个值。
}
反序列化:
测试代码:
package test.com;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class DeserializeExample {
public static void main(String[] args) {
Employee emp = null;
try (FileInputStream fileIn = new FileInputStream("employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)) {
emp = (Employee) in.readObject();
System.out.println("Deserialized Employee...");
System.out.println("Name: " + emp.getName());
System.out.println("Salary: " + emp.getSalary());
// yearOfService 是 transient 的,所以它的值将是 0
System.out.println("Year of Service: " + emp.getYearOfService());
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
}
}
运行结果如下:
3、序列化Map对象:
测试代码:
package test.com;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;
//序列化Map对象:
//当需要将Map对象的状态(即其包含的键值对)保存到磁盘或通过网络发送时,可以使用ObjectOutputStream将Map对象序列化。
//序列化过程会遍历Map中的所有键值对,并将它们以及Map本身的状态信息转换为字节序列。
public class MapSerializationExample {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
try (FileOutputStream fileOut = new FileOutputStream("map.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
out.writeObject(map);
System.out.println("Serialized data is saved in map.ser");
} catch (IOException i) {
i.printStackTrace();
}
}
}
反序列化Map对象:
测试代码:
package test.com;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Map;
//当需要从磁盘读取或通过网络接收字节序列,并重新构造出原始的Map对象时,可以使用ObjectInputStream进行反序列化。
//反序列化过程会读取字节序列,并根据其中包含的信息重新构建出Map对象及其包含的键值对。
public class MapDeserializationExample {
public static void main(String[] args) {
try (FileInputStream fileIn = new FileInputStream("map.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)) {
@SuppressWarnings("unchecked")
Map<String, Integer> map = (Map<String, Integer>) in.readObject();
// 输出反序列化后的Map对象
for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}
} catch (IOException | ClassNotFoundException i) {
i.printStackTrace();
}
}
}
运行结果如下: