共计 3815 个字符,预计需要花费 10 分钟才能阅读完成。
前言
大家好啊,我是汤圆,明天给大家带来的是《Java 中的 IO 流 - 入门篇》,心愿对大家有帮忙,谢谢
因为 Java 的 IO 类有很多,这就导致我刚开始学的时候,感觉很乱,每次用到都是上网搜,后果每次用完就忘;
起初沉下心去看书学习,才明确都是有法则的;
这里先做个简略的介绍,作为入门级教程,前面还有很多要学习的,有空再整顿吧。
简介
文件 IO 流,次要有两种形式
- 字节流 :基于一般的 Java 对象,仅实用于Java 程序 之间的读写
- 字符流 :基于一般的文本字符串,不仅实用于Java 程序 之间的读写,也实用于 Java 程序和 其余语言程序 之间的读写
本例中用到的相干类如下:
所有的读写操作都是针对 内存 而言的,因为 程序 就是 运行 在内存 中
读操作就是从 磁盘文件或网络流 读到 内存,对于内存而言就是Input
写操作就是从 内存 写到 磁盘文件或网络流,对于内存而言就是Output
上面别离介绍这两种形式
字节流:基于一般的 Java 对象
字节流的读和写都是基于 Java 程序而言,比方在一个机器上的 Java 程序写入一个对象到文件,而后传输到另一个机器上的 Java 程序去读取文件中的对象
写入 Java 对象时,会先将 Java 对象序列化(对象转为字节),而后写入
读取 Java 对象时,会先将 Java 对象反序列化(字节转为对象),而后读取
写对象
将对象写入到文件中,须要先把对象序列化,而后再把序列化后的字节写入到文件中;
序列化就是将对象的属性信息转为一系列字节(不包含 transient 类型的属性,上面会介绍)
大略流程如下所示:
读对象
将对象从文件中读出来,须要先反序列化,而后再转为对应的 Java 对象,并复原对象属性值
反序列化就是将一系列字节转为实在的对象实例(不包含 transient 类型的属性)
大略流程如下所示:
transient
该修饰符 字面意思是刹时的,短暂的
用在对象的属性上,就示意这个属性是 临时无效 的,等 序列化的时候会生效
在反序列化的时候,这个属性就会为 null(如果属性是对象援用)或 根底类型的默认值(如果属性是根底类型)
比方明码等比拟隐衷的属性,咱们就能够设置为transient
,这样就不会在传输过程中被被人拦挡,从而破解出明码
代码
public class ObjectIoDemo {public static void main(String[] args) throws IOException, ClassNotFoundException {InnerObject object1 = new InnerObject(10);
String filename = "object.bin";
writeObjectFun(filename, object1);
InnerObject objectReturn = (InnerObject) readObjectFun(filename);
System.out.println(objectReturn);
}
// 写对象 到指定文件
public static void writeObjectFun(String filename, Object o) throws IOException {FileOutputStream fileOutputStream = new FileOutputStream(filename);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(o);
// 敞开流,fileOutputStream 会一并敞开
objectOutputStream.close();}
// 读对象 从指定文件
public static Object readObjectFun(String filename) throws IOException, ClassNotFoundException {FileInputStream fileInputStream = new FileInputStream(filename);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Object o = objectInputStream.readObject();
// 敞开流,fileInputStream 会一并敞开
objectInputStream.close();
return o;
}
}
class InnerObject implements Serializable{
@Override
public String toString() {
return "InnerObject{" +
"num=" + num +
'}';
}
public InnerObject(int num) {this.num = num;}
public int getNum() {return num;}
public void setNum(int num) {this.num = num;}
private int num;
}
如果要写入的 Java 对象没有序列化,则会报错如下
Exception in thread "main" java.io.NotSerializableException: com.jalon.basic.io.InnerObject
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at com.jalon.basic.io.ObjectIoDemo.writeObjectFun(ObjectIoDemo.java:28)
at com.jalon.basic.io.ObjectIoDemo.main(ObjectIoDemo.java:19)
字符流:基于一般文本字符串
字符流写入到文件中的数据,是作为通用文本数据来解决的,这样 Java 程序和其余程序都能够去读写这个文件
写文本
大抵流程如下:
读文本
大抵流程如下:
BufferedReader 和 BufferedWriter 的作用
为什么要用缓冲区呢?间接用 FileReader 和 FileWriter 不也能够吗?
如果间接用 FileWriter
和FileReader
是能够运行,只不过效率会比拟低,因为每一次的读写都是针对磁盘操作的;
而 BufferedWriter
和BufferedReader
这两个缓冲区能够缩小磁盘的读写次数;
BufferedReader
:程序能够从磁盘一次性读很多数据到缓冲区,再从缓冲区一次次读,等缓冲区为空时再去磁盘读;
BufferedWriter
:程序能够写屡次到缓冲区,等缓存区满了再一次性写入到磁盘中
代码
public class TextIoDemo {public static void main(String[] args) throws IOException {
String filename = "string.txt";
writeString(filename, "hello world");
String res = readString(filename);
System.out.println(res);
}
// 写字符串到指定文件
public static void writeString(String filename, String content) throws IOException {FileWriter fileWriter = new FileWriter(filename);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(content);
bufferedWriter.close();}
// 从指定文件读取字符串
public static String readString(String filename) throws IOException {FileReader fileReader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line=bufferedReader.readLine())!=null){stringBuilder.append(line);
}
bufferedReader.close();
return stringBuilder.toString();}
}
总结
IO 流分为 字节流 和字符流
如果读写两边都是 Java 程序,则举荐用字节流,序列化和反序列化很不便
如果一边是 Java 程序,另一边是其余语言的程序,则举荐用字符流,读写的内容都是文本格式,不便解析
下面只是列出了个别读写类,Java 中读写类还有很多,大家感兴趣的能够去 java.io 下查看
参考
- 《Head First Java》(第二版)
- 《Java 核心技术卷一》(第十版)
- 《Java 编程思维》(第四版)
后记
最初,感激大家的观看,谢谢