java IO
一、字节输入流
- InputStream
- 所有字节输入流的父类
- read() 抽象方法,需要子类重写 返回int类型,值范围:0-255;如果已经读取到尾部,则返回-1
- read(byte b[]);read(byte b[],int off,int len)
- 读取数据保存到byte中,返回读取的byte个数,值范围:0~len;如果读取到尾部则返回-1;如果len=0,则返回0
- 必须off+len<=b.length off>=0 len>=0 ,否则抛出异常
- 底层还是调用read()
- skip(long n) 入参n标识要跳跃的字节个数 返回值为实际跳跃的个数 实际值可能比指定值小,比如已经到流尾部
- available() 需要子类重写
- close() 关闭流
- mark(int readLimit) reset() markSupported()
- markSupported返回boolean类型,判断当前流是否支持mar和reset方法
- mark方法标记当前位置,调用reset方法时,返回mark的位置,可以重复读取;入参作用未知???
- FilterInputStream 装饰模式,构造函数会输入InputStream类型对象,所有方法是直接调用此对象方法 属性InputStream in
- FileInputStream 实现InputStream方法
- 内部属性 FileDescriptor FileChannel
- read open方法都是native方法
- close方法需要关闭FileDescriptor和FileChannel
- BufferedInputStream继承FilterInputStream类 缓存流 允许mark方法
- 内部属性 DEFAULT_BUFFER_SIZE MAX_BUFFER_SIZE两个常量
- 内部缓存数组:byte[] buf
- 原子化操作:AtomicReferenceFieldUpdater bufUpdater 保证线程安全
- 数组中有效元素长度:count 当前指针位置:pos
- 标记位置:markpos 没有标记时,markpos为-1
- 标记数据长度:marklimit mark方法参数 当marklimit+markpos>buf.length时,buf会扩容
- 核心方法:fill() 填充缓冲数组数据
二、字节输出流
- OutputStream 抽象类,相对于输入流方法少
- 输出:write(int b) 子类必须实现此方法
- 输出:write(byte[] b) write(byte[],inf off,int len)底层仍然是调用write(int b)
- 刷新:flush() 将缓存输出到流中
- 关闭:close() 关闭流
- FilterOutputStream 装饰模式 包含OutputStream out成员变量
- write(int b) write(byte[] b) write(byte[],int off,int len)直接调用out方法
- flush()方法,也是直接调用out的flush方法
- close()方法 使用java7的try(){}格式,资源自动调用close方法 ;资源必须实现AutoCloseable try(OutputStream ostream=out){flush();}
三、字符输入流
四、字符输出流
五、RandomAccessFile
- 构造函数 RandomAccessFile(File file,String mode); RandomAccessFile(String name,String mode) 底层都是调用RandomAccessFile(File file,String mode).
- mode:r,rw,rws,rwd;
- r为只读模式,如果系统没有此文件,会抛出异常;此模式下,调用write等方法会抛异常
- rw为读写模式,如果系统没有此文件,会自动创建文件;可读可写
- rws有rw模式的所有功能,并且修改文件内容或者元数据,会同步到底层存储介质
- rwd有rw模式的所有功能,并且修改文件内容,会同步到底层存储介质
六、Serializable 序列化标志
- 规范
- static和transient修饰的field的状态不会保存,网络传输中会保存为null。
- 父类实现了serializable接口,子类不必实现serializable接口,子类会自动实现此接口;
- 子类实现了serializable接口,父类没有实现serializable接口,只要父类有空构造函数,仍能实现父子序列化
- 类中成员变量必须实现serializable接口,才能实现序列化;如果类成员变量为父类,则父类必须实现serializable接口
- 进阶
- transient字段也可以被序列化,可以手动指定序列化字段,有啥用?如果想要序列化,不使用transient修饰即可
- 使用Externalizable接口;重写其中的方法,手动控制序列化。java8模式下测试,无效,无论怎写都序列化所有属性,包括transient修饰的属性
- transient字段也可以被序列化,可以手动指定序列化字段,有啥用?如果想要序列化,不使用transient修饰即可
七、面试
- PrintStream,BufferWirter,PrintWriter区别
- PrintStream和PrintWriter功能差不多,都是装饰类;前者装饰字节流,后者字节流和字符流都可以;都不抛出异常;都可以设置自动刷新;文本输出使用此装饰类
- BufferWriter提供缓存功能,可以提高输出效率。必须使用flush刷新操作才能输出;只能处理字符,处理字节需要BufferOutputStream


浙公网安备 33010602011771号