[TOC]
基本数据类型流
可以读写基本数据类型
数据输入流:DataInputStream
DataInputStream(InputStream in)
数据输出流:DataOutputStream
DataOutputStream(OutputStream out)
特点:
1.该流是一个字节流,可以读写字节的同时,还能够读写基本数据类型
2.通过数据类型输出流写入到文件中,使用文本文件打开是不能阅读,提高了基本数据类型在文件中保存的安全性
3.读的时候必须和写的顺序保持一致,提高了基本数据类型在文件中保存的安全性
PrintWriter / PrintStream
PrintWriter / PrintStream
概述:向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print 方法。
特点:
只能写数据,不能读取数据。
可以操作任意类型的数据。
如果启动了自动刷新,能够自动刷新。
RandomAccessFile概述:此类的实例支持对随机访问文件的读取和写入。
特点
1.RandomAccessFile类不属于流,是Object类的子类。
2.包含了InputStream和OutputStream的功能。
3.能够读写基本类型
4.支持对随机访问文件的读取和写入。 getFilePointer/seek
long getFilePointer() 获取文件指针
long length() 返回此文件长度
void seek(long pos) 设置文件指针
void setLength(long newLength) 设置此文件长度
序列化流
序列化流ObjectOutputStream
反序列化流ObjectInputStream
ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。
可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。
如何实现序列化?
类通过实现 java.io.Serializable 接口以启用其序列化功能。
未实现此接口的类将无法使其任何状态序列化或反序列化,该接口没有任何方法,是一个标机接口。
未实现序列化抛出未序列化异常:NotSerializableException。
序列化数据后,再次修改类文件,读取数据会出问题,如何处理?
使用transient关键字声明不需要序列化的成员变量。
Properties类
Properties概述: Properties 类表示了一个持久的属性集;Properties 可保存在流中或从流中加载;属性列表中每个键及其对应值都是一个字符串。
Properties可以当做Map集合类使用
Properties的特殊遍历功能
public Object setProperty(String key,String value)
public String getProperty(String key)
public Set
Properties和IO流结合使用
public void load(Reader reader)
public void store(Writer writer,String comments)
配置文件:
1.Properties 轻量级,在网络中传输带宽小,本地存储数据量简单,就是键值对结构,理解为一个类似于map的文件
2.XML 重量级,结构化清晰,可读性强,能够存储复杂结构的数据
持久化:
1.txt
2.Properties
3.XML
4.json
5.数据库
NIO流
NIO
为什么了有了IO,还需要有NIO?
NIO在JDK1.4后引入的
NIO是面向块(缓冲区)编程,旧IO是面向流编程
IO NIO
面向流 面向缓冲区
阻塞IO 非阻塞IO
无 选择器
Java中针对IO的一些核心的包和接口、类
java.nio 主要包含了各种与Buffer相关的类
java.nio.channel 主要包含了与Channel和Selector相关的类和接口
java.nio.charset 主要包含了与编码相关的类接口
java.nio.channels.spi 主要包含了与Channel相关的服务提供者编程接口
javan.nio.charset.spi 主要包含了与charset相关的服务提供者编程接口
目前需要掌握的核心就是四个包
Buffer
Channel
CharSet
Selector
面向缓冲区编程:
数据的读写必须经过缓冲区
我们可以使用Buffer所对应的子类来数据从通道(Channel)流向缓冲区
从缓冲区写到通道叫做读取缓冲区
Buffer
Buffer是一个抽象类,针对缓冲区封装的一个类,提供相应的方法来操作这个缓冲区
子类有
ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer
核心类
ByteBuffer和CharBuffer
ByteBuffer有一个子类 MappedByteBuffer
MappedByteBuffer类能够将文件直接映射到内存中,那么这样我们就可以像访问内存一样访问文件,非常方便
获取Buffer
获取ByteBuffer
static ByteBuffer allocate(int capacity)
分配一个新的字节缓冲区。
static ByteBuffer allocateDirect(int capacity)
分配新的直接字节缓冲区。
二者获取Buffer的区别
1.创建普通Buffer成本低,读写的效率不高
2.因为创建直接Buffer成本高,所以我们一般用在Buffer生存周期较长的时候使用
3.只有ByteBuffer才能够创建直接Buffer,其他的Buffer对象是不能够创建
4.如果创建了直接Buffer但是我又想要使用其他Buffer的功能,可以将ByteBuffer转换成其他Buffer
asIntBuffer()
四个非常重要的概念
capacity: 缓冲区的容量,不可以为负数,一旦创建了就不能够改变
limit: 无效缓冲区的第一个位置索引,limit后面的数据既不可读,也不可写
position : 下一个可以被读取或者写入的缓冲区位置索引
mark: 标记索引,该索引能够用于下次读取或者写入,它只能够在0-position之间
四个系数的关系:
0 < mark < postion < limit < capacity
五个方法
flip(): 将写模式切换为读模式, 将limit的值改为postion的值,同时将postion归0
特点: 就是为下一次数据的读取做好准备
clear(): 将读模式切换为写模式,将limit改为capacity的值,同时将postion归0
特点: 就是为下一次数据的写入做好准备
put(): 相对读取,向Buffer中存储数据
get(): 相对读取,从Buffer中获取数据
mark(): 设置标记位
reset(): 重置
hasRemaining(): 判断当前位置和limit之间是否还有元素可处理
绝对读取: get(index) 不会影响position的位置
相对读取: put() get() 会影响,每次读取一次,指针后移
Channel 通道
Channel 通道
Channel原理类似于传统的流对象, FileInputStream FileOutputStream
但是有3个主要的区别
1.程序如果想要读取Channel中的数据,不能够直接读写,必须经过Buffer 【唯一性】
2.通过Channel通道既能够读取也能够写入数据 【双向性】
3.Channel能够将指定的部分或者全部文件映射到内存中
全部映射
MappedByteBuffer
部分文件映射
Java中为Channel提供了如下常用的类
FileChannel 和文件相关的通道
DatagramChannel 和UDP协议传输数据相关的通道
SocketChannel 针对TCP协议客户端Socket提供的通道
ServerSocketChannel 针对TCP协议服务器端Socket提供的通道
获取FileChannel对象
和文件相关的普通流有哪些?
FileInputStream FileOutputStream RandomAccessFile
常用的方法
read() : 将Channel中的数据读取到Buffer中
write() : 向Buffer中写入数据
map(): 将channel中的数据全部或者部分映射到Buffer中