JAVA-IO流
IO流的四大家族
**- InputStream 字节输入流
- OutputStream 字节输出流
- Reader 字符输入流
- Writer 字符输出流
- 四大家族的首领都是抽象类
-注意: 在JAVA中只要“类名”以Stram结尾的都是字节流,以“Reader”/“Writer”结尾的都是字符流**,所有的流都实现了Closeable接口,都是可关闭的,都有close()方法。所以的输出流都实现了Flushble接口,都是可刷新的,都有flush()方法。
需要掌握的流共16个
文件专属:
java.io.FileInputStream(掌握)
java.io.FileOutputStream(掌握)
java.io.FileReader
java.io.FileWriter转换流:(将字节流转换成字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter
缓冲流专属:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream
数据流专属:
java.io.DataInputStream
java.io.DataOutputStream
标准输出流:
java.io.PrintWriter
java.io.PrintStream(掌握)
对象专属流:
java.io.ObjectInputStream(掌握)
java.io.ObjectOutputStream(掌握)
.FileInputStream的使用
package IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 万能流什么文件都可以读
*/
public class FileInputStreamTest {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\course\\a.txt");
//数组读取
byte[]bytes = new byte[4];
/* while (true){
int readCount = fis.read(bytes);
//读取文件内容,读取完毕下一个节点返回-1,说明文件读取完。
if (readCount!=-1){
break;
}
//把byte数组转换成字符串,读到多少个转换多少个
System.out.print(new String(bytes,0,readCount));
}*/
int readCount = 0;
while ((readCount=fis.read(bytes))!=-1){
System.out.println(new String(bytes,0,readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis!=null){
try {
//关闭流
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileOutputStream的使用
package IO;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 文件输出流,负责写
* 从内存在硬盘
*/
public class FileOutputStreamTest {
public static void main(String[] args) {
FileOutputStream fos = null;
try {
//a文件不存在的时候,会自动新建
//这种方式会将源文件全部清空,从新写入
// fos = new FileOutputStream("a.txt");
//以追加的方式在文件的末尾写入,不会清空原内容
fos = new FileOutputStream("a.txt",true);
//开始写
byte[]bytes = {97,98,99,100};
//将byte数组全部写出
fos.write(bytes);
//将byte数组一部分写出
fos.write(bytes,0,2);
//写完以后一定要刷新
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文件的复制
文件复制的原理
package IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 文件的拷贝,拷贝过程一边读一边写,
* 文件类型随意,什么文件都可以拷贝
*/
public class Copy {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("D:\\course\\a.txt");
fos = new FileOutputStream("D:\\zn\\a.txt");
//一边读一边写
byte[]bytes = new byte[1024*1024];//1MB(1次最多拷贝1M)
int readCount = 0;
while ((readCount = fis.read(bytes))!=-1){
fos.write(bytes,0,readCount);
}
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
序列化与反序列化
- 参与序列化和反序列化必须实现Ssrializable接口,这个接口什么代码也没有,只是起到一个标识的作用,JAVA虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇。JAVA虚拟机看到这个接口后,会为该类自动生成一个序列化版本号
序列化版本号的用途
- JAVA语言中采什么机制区分类
第一:首先通过类名进行对比,如果类名不同,肯定不是同一个类。
第二:如果类名一样,靠序列化进行区分
- 假设张三写了一个com.beijing.java.bean.Student implements Serializable
李四写了一个com.beijing.java.bean.Student implements Serializable
不同的人编写同一个类,但”这两个类确实不是同一个类“,这时候序列化就起到作用了。对于JAVA虚拟机来说,JAVA虚拟机是可以区分这两个类的,因为这两个类都实现了Ssrializable接口,都是默认序列化版本号,他们序列化版本号不同,所以就区分开了。 - 自动生成序列化版本号缺点是:一旦代码确定后,不能在进行后续的修改,因为只要修改,必然会重新编译,此时会生成新的版本号,这个时候JAVA虚拟机就会认为这是一个全新的类。
- 结论:凡是一个类实现了Ssrializable接口,建议给该类提供一个固定不变的序列化版本号。这样即使代码修改,但是版本号没变,JAVA虚拟机会认为是同一个类。
Properties
Properties:是一个Map集合,Key和Value都是String类型。
主要用于配置文件。