Java基础第三篇-IO
Charter 15 输入/输出
主要是总结了一下文件操作以及序列化,NIO。
1.File类
访问文件名相关的方法:
String getName()
String getPath()
File getAbsoluteFile()
String getAbsolutePath()
String getParent()
文件检测相关方法
boolean exists()
boolean canWrite()
boolean canRead()
boolean isFile()
boolean isDirectory()
获取常规文件信息
long lastModified()
long length()
文件操作相关方法
boolean createNewFile():如果File对象对应文件不存在,该方法会新建一个指定的新文件
boolean delete():删除File对象对应的文件或路径
目录操作相关方法
boolean mkdir():创建一个File对象对应的目录
String[] list():列出File对象所有子文件名和路径名
File[] listFiles(): 列出File对象所有子文件和路径
static File[] listRoots():列出系统所有根路径
例子:
1 | public class FileTest { |
2.Java的IO流
InputStream/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流
OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流
3.对象序列化
是什么:实现序列化的Java对象转换成字符序列,这些字符序列可以保存到磁盘上。
为什么:为了让对象可以脱离程序的运行而独立存在。
主要是Serializable这个接口
使用对象流实现序列化
1.创建一个ObjectOutputStream,这是一个输出流
1 | ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(“Object.txt”)); |
2.调用writeObject()方法输出可序列化对象
1 | oos.writeObject(per); |
3.Person类实现Serializable接口
1 | public class Person implements Serializable |
4.使用ObjectOutputStream将Person对象写入磁盘文件
1 | public class WriteObject |
从二进制流中恢复Java对象
1.创建ObjectInputStream输入流
1 | ObjectInputStream ois = new ObjectInputStream(new FileInputStream(“Object.txt”)); |
2.调用readObject()方法读取流中的对象
1 | Person p = (Person)ois.readObject(); |
4.NIO
由于流输入/输出一次只能处理一个字节,为了解决效率不高的问题,从JDK1.4开始加入了一些列改进输入/输出处理的新功能,这些功能简称新IO(NIO)
概述
新IO将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样访问文件,大大提高了处理输入\输出的速度
相关包如下:
java.nio:包含于Buffer相关的类
java.nio.channels:包含Channel和Selector相关的类
java.nio.charset:包含字符集相关的类
java.nio.channels.spi:包含与Channel相关的服务提供者编程接口
java.nio.charset.spi:包含字符集相关的服务提供者编程接口
Channel和Buffer是其中核心。
Channel与传统的InputStream、OutputStream最大区别是它提供了一个map()方法,可以将数据映射到内存中。
Buffer本质上是一个数组,发送到Channel的对象都要先放到Buffer中,Channel读取数据也要到Buffer中读取。
Buffer中有3个重要概念
- capacity:缓冲区的容量,创建后不可改变,不可为负值
- limit:第一个不应该被读出或者写入的缓冲区位置索引,换句话说,这个索引后的区域都无法读写
- position:用于指明下一个位置索引
例子:
1 | public class BufferTest { |
打印结果:
1 | capacity:8 |
- flip():把limit设置为position所在位置,将position设置为0,也就是做好输出数据准备
- clear():将position设置为0,将limit设置为capacity,为再次输入数据做好准备,但是内容并没有被清空。
上面这个程序的执行过程就是
- 加入三个元素后,position来到了3
- 执行flip(),limit设置为position的值,也就是3,position设置为0
- 执行clear(),position设置为0
为什么在写入数据完成后,需要调用flip()方法呢,因为这个时候limit到了position的位置,也就是说后面的无数据区域都无法访问,避免了读到null值。
5.使用Channel
Channel最常用的三类方法shi map()\read()\write(),其中map()方法用于将Channel对应的数据映射成ByteBuffer
例子:
1 | public class FileChannelTest { |
通过MappedByteBuffer将channel中的数据映射成ByteBuffer,然后写入FileChannel。
除了这种一次性把全部数据映射的方式,我们也可以采取类似传统字节流的方式
例子:
1 | public class ReadFile { |
通过flip()和clear()进行读取的限制,防止读出null值。