Create by westfallon on 8/15
流
- 在java API中,可以从其中读入一个字节序列的对象叫做输入流,可以向其中写入一个字节序列的对象叫做输出流,这些字节序列的来源地和目的地可以是文件,也可以是网络连接,甚至是内存块
读写文件
-
InputStream类有一个抽象方法abstract int read(),这个方法将读入一个字节并返回,或在遇到结尾时返回-1 -
read和write方法在执行时都将被阻塞,直至字节确实被读入或写出 - 当完成对流的读写时,应该通过调用
close方法来关闭它 - 关闭一个输出流的同时还会冲刷用于该输出流的缓冲区:所有被临时置于缓冲区中,以便用更大包的形式传递的字符将会在关闭输出流时都将被送出。特别是,如果不关闭文件,那么写出字节的最后一个包可能永远都不会得到传递
-
InputStream、OutputStream、Reader和Writer都实现了Closeable接口,这个接口扩展了AutoCloseable接口,因此对任何Closeable进行操作时,都可以使用try-with-resource语句
组合过滤器
-
InputStream和OutputStream只支持在字节级别上的读写,DataInputStream和DataOutputStream无法直接读取文件 - 所以可以嵌套使用
FileInputStream fin = new FileInputStream("filePath"); DataInputStream din = new DataInputStream(fin); double s = din.readDouble(); - 可以通过嵌套过滤器来添加多重功能,例如想使用缓冲机制
DataInputStream din = new DataInputStream( new BufferInputStream( new FileInputStream("filePath")));
对象流与序列化
- Java语言支持一种称为对象序列化(object serialization)的机制,可以将任何对象写出到流中,并在之后将其读回
- 对希望在对象流中储存或恢复的所有类都应该进行一下修改,这些类必须实现
Serializable接口 - 每个对象都是用一个序列号(serial number)保存的
- 对象序列化算法:
- 遇到的每一个对象引用都关联一个序列号
- 对于每个对象,当第一次遇到时,保存其对象数据到流中
- 如果某个对象之前已经被保存过,那么只写出“与之前保存过的序列号为x的对象相同”。在读回对象时,整个过程是反的
- 对于流中的对象,在第一次遇到其序列号时,构建它,并使用流中数据来初始化它,然后记录这个顺序号和新对象之间的关联
- 当遇到“与之前保存过的序列号为x的对象相同”标记时,获取与这个序列号相关联的对象引用
修改默认的序列化机制
- 某些数据域是不可以序列化的,例如,只对本地方法有意义的储存文件句柄或窗口句柄的整数值,这些信息在其他机器上是没有用处的
- Java中可以将域标记成
transient来防止其被序列化
为克隆使用序列化
- 序列化机制提供了一种克隆对象的简单途径,只要对应的类是可序列化的即可:直接将对象序列化到输出流中,然后将其读回。这样产生的新对象是对原有对象的深拷贝(deep copy)
文件
操作文件
-
Path和Files类封装了在用户机器上处理文件系统所需的所有功能
文件加锁机制
- 要锁定一个文件,可以使用
FileChannel类的lock或tryLock方法
或FileChannel channel = FileChannel.open(path); FileLock lock = channel.lock();FileLock lock = channel.tryLock(); - 第一个调用会阻塞直至可获得锁,而第二个调用将立即返回,要么返回锁,要么在锁不可获得的情况下返回null。这个文件将保持锁定状态,直至这个通道关闭,或者在锁上调用了
release方法 - 还可以通过以下方法调用锁定文件的一部分
或FileLock lock(long start, long size, boolen shared)FileLock tryLock(long start, long size, boolen shared)