概念
- I :input
- O:output
- java.io.* 包
- 通过IO可以完成对硬盘的读和写
字节流
- 万能流,一次读一个字节(byte) = 8个二进制位
- 啥都能读取
字符流
- 一次读一个字符
- 只能读纯文本文件 .txt
区分
- 在Java中类名以Stream结尾的都是字节流
- 以Writer/Reader结尾的都是字符流
所有的流都实现了Closeable接口,都是可以关闭的
- 流用完一定要关
所有的输出流都实现了Flushable接口,都是可刷新的
- 最后输出之后一定要flush()刷新一下(清空管道)

IO四大家族(都是抽象类)
- java.io.InputStream 字节输入流
- java.io.OutputStream 字节输出流
- java.io.Reader 字符输入流
- java.io.Writer 字符输出流
文件复制原理

需要掌握的流
文件专属流
- 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
File In/Out putStream
万能流,所有文件都可以用来读
int read() 读取第一个字节(每调用一次向下移一个)
int i = stream.read();
返回一个ascll码 读到末尾 ,读不到了就返回-1
int available() 返回流当中剩余的没有读到的字节数量
作用:一上来就可以获取它的总字节数量
int i = stream.available();
long skip() 跳过几个字节不读
用while循环读取文件
FileInputStream s = null;try {s = new FileInputStream("I_O/src/FileInputStreamTast01/My");byte[] bytes = new byte[14]; int i1 = 0 ;while( (i1 = s.read(bytes)) != -1){System.out.println(i1);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally{if (s != null) {try {s.close();} catch (IOException e) {e.printStackTrace();}}}
FileOutputStream
写完一定要flush() 刷新一下
构造方法里跟一个地址(只有地址)
会把地址里面的文件清空,后写入
构造方法里跟一个地址,true 表示追加写入
write() 写入
write(byte[]数组,开始下标,结束下标) 写入指定长度的文件
文件复制
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("E:\\仝子瑜\\tongziyu.jpg"); //创建输入流
out = new FileOutputStream("E:\\tongziyu.jpg"); //创建输出流
byte[] bytes = new byte[1024];
int i = 0;
while ((i = in.read(bytes)) != -1){ //读文件
out.write(bytes,0,i); //写文件
}
out.flush(); //刷新一下
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
FileReader
一次读取一个字符,只能读取普通文本文件
用char数组接收
和FileInputStream差不多,就是用char[]数组接收数据
FileWriter
一个写入一个字符 “a/中”
引用.flush() 刷新不要忘
BufferedReader/PrintStream
BufferedReader概念
- 带有缓冲区的字符输入流
- 使用时不惜要byte[] 或者 char[] 数组 自带缓冲
- 当一个流(包装流,处理流)的构造方法需要传进去一个流(节点流)的时候
- 关闭流时只需要管理包装流即可
String readLine() // 读取一行
String s = 引用.readLine();
读不到内容时会返回null
bufferedReader的构造方法里只能跟字符流
如果要用字节流,就需要转换流
转换流
FileInputStream in = new FileInputStream("路径"); //字节流
InputStreamReady ready = new InputStreamReady(in); // 转换成字符流
使用缓冲字符输入流读文件
BufferedReader s = null;
FileReader reader = null;
try {
reader = new FileReader("E:\\java\\Java 资料\\JAVA语法.TXT");
s = new BufferedReader(reader);
String s5 = null;
// 因为 readLine() 在都不到的情况下会返回null 由此判断
while ((s5 = s.readLine()) != null ){
System.out.println(s5);
}
}
PrintStream
- 标准输出字节
- 不需要使用close()关闭
- 标准输出流是指不再向控制台输出,而是指向这个文件输出↓
- PrintStream ps = new PrintStream(new FileOutputStream(“log”))
- System.setOut(ps); // 改变输出方向
- System.out.println(“HelloWorld”); // 不会输出到控制台,会输出到log文件里
File类
file对象
- 可能对应的是一个目录,或者文件
- 只是一个路径名的抽象表示形式
掌握File类的常用方法
- File s = new File(“路径”) // 创建file对象
- boolean exists(); //判断是否存在
- boolean mkdir() //以目录形式新建
- boolean mddirs() //以多重目录新建
- File getAbsoluteFile() //获取绝对路径
- String getParent() //获取父路径
- String getName() //获取文件名
序列化

- 序列化:Serialize
- 反序列化:DeSerialize
参与序列化的和反序列化的对象必须都要实现Serializable接口
Serializable只是一个标志性接口,里面没有任何代码
在java中如何区分一个类
- 类名
序列化版本号(实现Serializeble接口)
Jvm会自动给这个类一个序列化版本号<br />但是后期修改代码的时候,序列化版本号也会自动修改<br />**所以建议给一个不变的序列化版本号:**<br />private static final long serialVersionVID = ~~~L; //可参考源码
序列化多个对象,创建一个list集合,对象放进去,序列化集合即可
transient关键字(不参加序列化操作)
- 例如private transient String name;
- 表示序列化多个对象,创建一个e不参加序列化操作
writeObject(对象或者引用); // 序列化
readObject (); 反序列化
ObjectOutputStream s = null;
ObjectInputStream a = null;
try {
/* s = new ObjectOutputStream(new FileOutputStream("E:\\asd.TXT"));
s.writeObject(1);*/ // 序列化对象
a = new ObjectInputStream(new FileInputStream("E:\\asd.TXT"));
Object s1 = a.readObject(); //反序列化
System.out.println(s1);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally{
/*try {
*//*s.close();*//*
} catch (IOException e) {
e.printStackTrace();
}*/
}
路径问题
获取文件绝对路径
以前
FileReader reader = new FileReader(“thread/peizhi”)
这种路径的缺点是:移植性差,在IDEA中默认的当前路径是project的根
假设离开了IDEA换到了其他位置,可能当前路径就不是当前project的根了,此时路径无效
通用
只适合文件放在类路径下的
什么是类路径:凡是在src下的都是类路径下
src是类的根路径
String path = Thread.currentThread().getContextClassLoader().getResource(“classinfo.properties”).getPath();
解释:
- Thread.currentThread() // 得到当前线程对象
- getContextClassLoader() // 是线程对象的方法,可以获取到当前线程的类加载器对象。
- getResource() // 是类加载器的方法,当前线程的类加载器默认从类的根路径下加载资源。
适用于 linux系统
直接以流的方式返回
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("classinfo.properties");
直接返回一个InputStream流
资源绑定器
java.util.ResourceBundle 包下
实现
ResourceBundle resourceBundle = ResourceBundle.getBundle(“classinfo”);
通过key得到value
String value = resourceBundle.getString(“classname”);
// 得到对应的classname的value
注意
- 这里的后缀一定要去掉
- 只能绑定类路径下的配置文件(src下的 .properties文件)
