1.1.1 标准输入流
源数据源是标准输入设备(键盘、鼠标、触摸屏)等输入设备。在java中用System.in 得到一个InputStream字节输入流。
需求:在控制台输入一句话,然后原样输出
public static void main(String[] args) throws IOException { // 需求:输入一句话,然原样输出 InputStream in = System.in;
byte[] buf = new byte[1024]; int len; // buf中包含回车和换行 len = in.read(buf);
String str = new String(buf, 0, len); // System.out.println(Arrays.toString(buf)); System.out.println(str); } |
注意:
[1] 标准输入流以字节流流入内存,如果在控制台中输入字符,字符以默认编码(win简体:gbk)编码成字节进入标准输入流。
public static void main(String[] args) throws IOException { // 需求:从控制台高效读取一行数据。把一首诗写入文件。
InputStream in = System.in; InputStreamReader reader = new InputStreamReader(in, "GBK"); BufferedReader br = new BufferedReader(reader);
File file = new File("d:\\javatest\\k.txt"); FileWriter writer = new FileWriter(file); BufferedWriter bw = new BufferedWriter(writer);
String end = "bye"; while(true) { String line = br.readLine(); if(line.equals(end)) { break; }
bw.write(line); // bw.newLine(); }
bw.flush();
bw.close(); writer.close();
} |
1.1.2 标准输出流(PrintStream)
数据目的地是标准输出设备(显示器)等输出设备。在java中用System.out得到一个PrintStream 字节输出流(字节打印流)。提供了更强大的
println
打印方法用于打印各种数据类型。
需求:读取文件,显示到标准输出设备
public static void main(String[] args) throws IOException {
File file = new File("d:\\javatest\\k.txt");
FileReader reader = new FileReader(file); BufferedReader br = new BufferedReader(reader);
PrintStream ps = System.out;
String line; while( (line=br.readLine())!=null ) { ps.println(line); } } |
PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。
public static void main(String[] args) throws IOException {
String str = "hello中国"; byte[] buf = str.getBytes("utf-8");
PrintStream ps = System.out; ps.write(buf);
} |
1.1 字符打印流PrintWriter
自学研究
1.2 Scanner(C)
通过scanner扫描文件、字节流等
public static void main(String[] args) throws IOException {
// 扫描平台默认编码的文件 /*File file = new File("d:\\javatest\\j.txt"); Scanner sc = new Scanner(file); */
// 扫描指定编码的文件 Scanner sc = new Scanner(new FileInputStream(new File("d:\\javatest\\j-utf8.txt")), "UTF-8");
String line; while (sc.hasNextLine()) { line = sc.nextLine(); System.out.println(line); }
} |
1.3 序列化
把内存中的对象永久保存到硬盘的过程称为对象序列化,也叫做持久化。
把硬盘持久化的内存恢复的内存的过程称为对象反序列化。
1.3.1 Serializable
类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化,并抛出异常
Exception in thread "main" java.io.NotSerializableException: cn.sxt05.serializable.Student at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) at cn.sxt05.serializable.Test01.main(Test01.java:22) |
Serializable接口没有方法或字段,仅用于标识可序列化的语义
public class Student implements Serializable{ // 。。。 |
1.3.2 序列化对象
ObjectOutputStream 继承于OutputStream,专门用于把对象序列化到本地。提供了
writeXXX
writeObject() 用于写入一个对象
public static void main(String[] args) throws IOException {
Student stu = new Student("001", "大狗", 20, Gender.男);
/** * 方案1:取stu所有的属性,通过特定的字符串(-),把各个属性值连接起来 * 001-大狗-20-男 */
File file = new File("d:\\javatest\\l.txt"); FileOutputStream out = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(stu);
oos.close(); out.close(); } |
1.3.3 反序列化对象
ObjectInputStream 继承于InputStream ,专门用于把本地持久化内容反序列化到内存,提供了
readXXX
readObject() 用于读取一个序列化内容并返回一个对象。
public static void main(String[] args) throws IOException, ClassNotFoundException {
File file = new File("d:\\javatest\\l.txt");
FileInputStream in = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(in);
Student student = (Student) ois.readObject(); System.out.println(student.getId()); System.out.println(student.getName()); System.out.println(student.getAge()); System.out.println(student.getGender());
ois.close(); in.close(); } |
1.3.4 序列化版本
当序列化完成后,后期升级程序中的类(Student),此时再反序列化时会出现异常。
Exception in thread "main" java.io.InvalidClassException: cn.sxt05.serializable.Student; local class incompatible: stream classdesc serialVersionUID = -6288733824962181189, local class serialVersionUID = 1690603786167234505 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:687) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1876) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1745) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2033) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1567) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427) at cn.sxt05.serializable.Test02.main(Test02.java:16) |
异常原因:序列化流的serialVersionUID和升级后类的版本不匹配。
解决方案:给Student类加序列化版本号,有两种方式
|
default serial version ID 生成默认的serial version ID 一般值都是1L。
generated serial version ID 根据当前类的属性、方法生成一个唯一ID。
public class Student implements Serializable {
private static final long serialVersionUID = -1003763572517930507L; |
1.3.5 transient
开发过程中,如果想忽略某些字段不让其序列化时,可以使用transient修饰。
public class Student implements Serializable {
private static final long serialVersionUID = 7222966748321328300L;
private String id; private transient String name; private transient int age; private Gender gender; private String phone; |
1.4 DataInputStream/DataOutputStream
DataOutputStream 继承OutputStream,专门用于把基本java数据类型写入输出流。提供了writeXXX 写入基本java数据类型。
DataInputStream 继承于InputStream,允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。
DataInputStream/DataOutputStream 特别适合读取/写入在网络传输过程中的数据流。
写入基本java数据类型
public static void main(String[] args) throws IOException {
File file = new File("d:\\javatest\\n.txt"); FileOutputStream out= new FileOutputStream(file); DataOutputStream dos = new DataOutputStream(out);
dos.writeInt(10); dos.writeUTF("hello中国");
dos.close(); out.close();
System.out.println("写入完成");
} |
读取基本java数据类型
public static void main(String[] args) throws IOException {
File file = new File("d:\\javatest\\n.txt"); FileInputStream in = new FileInputStream(file); DataInputStream dis = new DataInputStream(in);
int a = dis.readInt(); String str = dis.readUTF();
System.out.println(a); System.out.println(str);
} |
注意:
以什么顺序写入基本java数据类型,就以什么顺序读取基本java数据类型。