zoukankan      html  css  js  c++  java
  • 流式IO读写

    1. FileInputStream 类直接继承了InputStream 的方法

    mark, markSupported, reset 方法

    而这几个方法都是空实现

    markSupported直接返回false

    所以对于FileInputStream类不支持随机访问文件,只能顺序的读写文件。

     

    2. NIO中的Buffer操作:

    Nio中的 java.nio.Buffer 这个类的几乎所有操作都是关于一个线性缓存区的,对于缓冲区的抽象,这个提供了下面的4个指示位:

        // Invariants: mark <= position <= limit <= capacity

        private int mark = -1;

        private int position = 0;

        private int limit;

    private int capacity;

    Capacity:缓冲区的容量

    其中的 capacity是缓冲区的容量大小,表示该缓冲区可以存储的元素个数。这里不是字节个数,而是element的个数,如果IntBuffer,则其所占的字节应该是:

    Capacity * 4:

    A buffer's capacity is the number of elements it contains. The capacity of a buffer is never negative and never changes.这个值在缓冲区初始化好之后,是不会变化的。它可以通过:capacity()方法获得。

    Position:缓冲区的当前读写位置

    表示缓冲区的当前位置,当缓冲区下一次调用get或者put方法时,就从 position++的位置开始。

        final int nextGetIndex() {                          // package-private

            if (position >= limit)

                throw new BufferUnderflowException();

            return position++; // 下一次读写的位置。

        }

    查看:java.nio.HeapByteBuffer 的 put , get方法,

        public ByteBuffer put(byte x) {

            hb[ix(nextPutIndex())] = x;

            return this;

    }

        public byte get() {

            return hb[ix(nextGetIndex())];

        }

    由上面的代码可见,buffer的读写操作,就是发生在position位置的。

    Buffer提供了两个方法对position进行操作:

     int

    position()
              Returns this buffer's position.

     Buffer

    position(int newPosition)

    可见我们可以手动的调整读写位置。

    3.mark

    Mark和reset常常是一对操作,这里的mark的语义和功能,同InputStream流类中提供的mark功能是完全一致的。

    Marks the current position in this input stream. A subsequent call to the reset method repositions this stream at the last marked position so that subsequent reads re-read the same bytes.

    就是在调用者方法时,将当前的position记录下来,

    这是 Buffer 的mark的实现:   

    public final Buffer mark() {

            mark = position;

            return this;

    }

    这是 ByteArrayInputStream类的实现:

        public void mark(int readAheadLimit) {

            mark = pos;

    }

    调用 reset方法,使得 position 赋值为 mark 中保存的上一次调用mark方法的值:

        public final Buffer reset() {

            int m = mark;

            if (m < 0)

                throw new InvalidMarkException();

            position = m;

            return this;

        }

    4. limit

    Limit的作用:用来限制读写的位置

        public final Buffer limit(int newLimit) {

            if ((newLimit > capacity) || (newLimit < 0))

                throw new IllegalArgumentException();

            limit = newLimit;

            if (position > limit) position = limit;

            if (mark > limit) mark = -1;

            return this;

    }

     

    3.Java.io

    BufferedReader类的 readLine 方法 ---》 调用 fill() 方法。

    Fill:

    n = in.read(cb, dst, cb.length - dst);

    java.io.Reader。 就是这个类的方法。

    这个类的 read 方法是:

    sd.read(cbuf, offset, length);

    sd = StreamDecoder.forInputStreamReader(in, this, charsetName);

    其中的 in 就是 InputStream

    所以最终是调用read方法来读取数据,

  • 相关阅读:
    解决jenkins sonar扫描中文名的文件会失败
    ukey命令行签名:解决safenet ukey 每次签名都要输入token password问题(批量签名)
    vmp如何使用命令行加壳exe或者dll
    tomcat 安装的jenkins的迁移解决磁盘爆满的问题
    cocoapods 执行pod trunk push 报错CDN: trunk URL couldn't be downloaded: https://raw.githubusercontent.com/CocoaPods/Specs/master/Spec
    使用NodeJs搭建的小型web应用
    对WebSocket技术的学习与探索(一)
    Git本地操作相关介绍
    NodeJs入门学习(一)
    ES6深入学习记录(三)编程风格
  • 原文地址:https://www.cnblogs.com/a-ray-of-sunshine/p/4642831.html
Copyright © 2011-2022 走看看