Thinking in Java (8)

第十八章 Java I/O系统  

在Java中把不同的输入/输出源抽象表述为"流"

1、分类

1.1、按流向分(这里的输入、输出都是从程序运行所在的内存的角度划分)

输入流:只能从中读取数据,而不能向其写入数据

输出流 :只能向其写入数据,而不能从中读取数据

1.2、按操作单元分

字节流:以字节(8bit)为单位

字符流:以16位字符为单位

1.3、按角色分

节点流:可以从/向一个特定的IO设备(如磁盘、网络)读/写数据的流

处理流:处理流是对一个已存在的流进行连接或封装,通过封装后的流来实现数据读/写功能

2、RandomAccessFile

“随机访问”文件,既可以读取文件内容,也可以向文件输出,可以直接跳转到文件的任意地方读写数据。

public class Test {

    public static void main(String[] args) throws Exception {
        RandomAccessFile accessFile = new RandomAccessFile("poet.txt", "rw");
        byte[] buffer = new byte[1024];
        while (accessFile.read(buffer) > 0){
            System.out.println(new String(buffer));
        }
        accessFile.write("欲穷千里目".getBytes());
        accessFile.write("更上一层楼".getBytes());
    }
}

3、序列化

3.1、Serializable   标记接口

实现Serializable的反序列化无须通过构造器来初始化Java对象

  • 所有保存到磁盘的对象都有一个序列化编号
  • 当程序试图序列化一个对象时,程序将先检查该对象是否已经被序列化过,只有该对象从未被序列化过(在本次虚拟机中),系统才会将该对象转换成字节序列并输出
  • 如果某个对象已经序列化过,程序将只是直接输出一个序列化编号,而不是再次重新序列化该对象

3.2、Externalizable

实现Externalizable的反序列化必须提供public的无参构造函数

需要实现readExternal、writeExternal方法

注意:

  • 对象的类名、实例变量(基本类型、数组、引用)都会被序列化;方法、类变量、transient实例变量都不会被序列化
  • 实现Serializable接口的类中用transient修饰的实例变量都不会被序列化
  • 保证序列化对象的实例变量类型也是可序列化的,否则用transient修饰
  • 反序列化对象时必须有该对象的class文件,读取顺序与写入顺序相同

4、NIO

4.1、Buffer

A buffer is a linear, finite sequence of elements of a specific primitive type.  Aside from its content, the essential properties of a buffer are its capacity, limit, and position.

抽象类,缓存数据的容器,常用子类:ByteBuffer、CharBuffer等,静态方法XxxBuffer allocate(int capacity) 创建对应的实例对象,Buffer中的几个重要概念:

capacity:缓冲区容量

limit:可读写界限

position:下一个可读写位置索引

mark:已读写区域中的标记

0<=mark<=position<=limit<=capacity

Buffer中的几个重要方法:

flip():设置 limit=position,position=0,可以从buffer读取数据

clear():设置position=0,limit=capacity,可以向buffer写入数据

4.2、Channel

A channel represents an open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, for example reading or writing.

接口,类似流对象,常用的实现类:FileChannel、DatagramChannel、SocketChannel、ServerSocketChannel等,Channel中的几个重要方法:

read():Reads a sequence of bytes from this channel

write() :Writes a sequence of bytes to this channel

map():Maps a region of this channel's file directly into memory

public class Test{

    public static void main(String[] args) throws Exception{
        FileInputStream in = new FileInputStream("poet.txt");
        FileChannel fc = in.getChannel();
        ByteBuffer bf = ByteBuffer.allocate(1024);
        while (fc.read(bf)!=-1){
            bf.flip();
            Charset cs = Charset.forName("UTF-8");
            // 解码器
            CharsetDecoder cd = cs.newDecoder();
            CharBuffer cb = cd.decode(bf);
            System.out.println(cb);
            bf.clear();
        }
        fc.close();
        in.close();
    }
}

File、Path访问文件系统接口

Files、Paths文件系统工具类

不要忘记关闭IO资源!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值