ImageInputStreamImpl基础实现

wen java案例 1

本文目录导读:

ImageInputStreamImpl基础实现

  1. 核心类结构
  2. 基础实现方法
  3. 自定义实现示例
  4. 使用示例

我将为你详细解析 ImageInputStreamImpl 的基础实现,这是 Java Image I/O API 中用于读取图像数据的关键抽象类。

核心类结构

public abstract class ImageInputStreamImpl implements ImageInputStream {
    // 关键成员变量
    protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;  // 默认大端序
    protected long streamPosition = 0L;                    // 当前流位置
    protected long flushedPosition = 0L;                   // 已刷新位置
    protected int bitOffset = 0;                           // 位偏移量(用于位级操作)
    // 关闭状态
    private boolean closed = false;
    // 流长度(可选)
    protected long length = -1L;
}

基础实现方法

位置管理

public class ImageInputStreamImpl {
    // 获取当前位置
    @Override
    public long getStreamPosition() {
        checkClosed();
        return streamPosition;
    }
    // 设置位置(前向seek)
    @Override
    public void seek(long pos) throws IOException {
        checkClosed();
        // 验证位置有效性
        if (pos < flushedPosition) {
            throw new IndexOutOfBoundsException(
                "pos < flushedPosition!");
        }
        // 更新位置
        streamPosition = pos;
        bitOffset = 0;  // 重置位偏移
    }
    // 跳过字节
    @Override
    public long skipBytes(long n) throws IOException {
        checkClosed();
        if (n < 0) {
            return 0;  // 不支持向后跳转
        }
        long newPos = streamPosition + n;
        long oldPos = streamPosition;
        // 如果超过文件末尾,修正位置
        if (length != -1L && newPos > length) {
            newPos = length;
        }
        streamPosition = newPos;
        return streamPosition - oldPos;
    }
}

字节读取方法

public class ImageInputStreamImpl {
    // 读取单字节
    @Override
    public int read() throws IOException {
        checkClosed();
        bitOffset = 0;
        byte[] b = new byte[1];
        int result = read(b, 0, 1);
        return result == -1 ? -1 : b[0] & 0xFF;
    }
    // 读取字节数组
    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        checkClosed();
        if (b == null) {
            throw new NullPointerException("b == null!");
        }
        if (off < 0 || len < 0 || off + len > b.length) {
            throw new IndexOutOfBoundsException();
        }
        if (len == 0) {
            return 0;
        }
        bitOffset = 0;
        // 需要子类实现具体的读取逻辑
        return 0;  // 抽象方法
    }
    // 读取所有剩余字节
    @Override
    public int readBytes(byte[] b, int off, int len) throws IOException {
        int total = 0;
        while (total < len) {
            int count = read(b, off + total, len - total);
            if (count == -1) {
                break;
            }
            total += count;
        }
        return total;
    }
}

位级操作

public class ImageInputStreamImpl {
    // 读取指定位数
    @Override
    public int readBits(int numBits) throws IOException {
        checkClosed();
        if (numBits < 0 || numBits > 64) {
            throw new IllegalArgumentException();
        }
        if (numBits == 0) {
            return 0;
        }
        // 累积位缓存
        long bits = 0;
        int remaining = numBits;
        while (remaining > 0) {
            // 如果当前字节已读完,读取下一个字节
            if (bitOffset == 0) {
                int b = read();
                if (b == -1) {
                    throw new EOFException();
                }
                savedBitCache = b;
            }
            // 计算可用的位数
            int available = 8 - bitOffset;
            int toRead = Math.min(remaining, available);
            // 提取位数
            int shift = available - toRead;
            long value = (savedBitCache >> shift) & 
                        ((1L << toRead) - 1);
            // 更新缓存
            bits = (bits << toRead) | value;
            bitOffset += toRead;
            if (bitOffset == 8) {
                bitOffset = 0;
            }
            remaining -= toRead;
        }
        return (int) bits;
    }
    // 设置位偏移
    @Override
    public void setBitOffset(int bitOffset) {
        checkClosed();
        if (bitOffset < 0 || bitOffset > 7) {
            throw new IllegalArgumentException();
        }
        this.bitOffset = bitOffset;
    }
}

字节顺序处理

public class ImageInputStreamImpl {
    // 设置字节顺序
    @Override
    public void setByteOrder(ByteOrder byteOrder) {
        checkClosed();
        this.byteOrder = byteOrder;
    }
    // 获取字节顺序
    @Override
    public ByteOrder getByteOrder() {
        checkClosed();
        return byteOrder;
    }
    // 按当前字节顺序读取短整数
    @Override
    public short readShort() throws IOException {
        checkClosed();
        bitOffset = 0;
        int b1 = read();
        int b2 = read();
        if (b1 == -1 || b2 == -1) {
            throw new EOFException();
        }
        if (byteOrder == ByteOrder.BIG_ENDIAN) {
            return (short) ((b1 << 8) | b2);
        } else {
            return (short) ((b2 << 8) | b1);
        }
    }
    // 按当前字节顺序读取整数
    @Override
    public int readInt() throws IOException {
        checkClosed();
        bitOffset = 0;
        int b1 = read();
        int b2 = read();
        int b3 = read();
        int b4 = read();
        if (b1 == -1 || b2 == -1 || b3 == -1 || b4 == -1) {
            throw new EOFException();
        }
        if (byteOrder == ByteOrder.BIG_ENDIAN) {
            return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
        } else {
            return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
        }
    }
}

流管理

public class ImageInputStreamImpl {
    // 刷新(丢弃已读数据)
    @Override
    public void flushBefore(long pos) throws IOException {
        checkClosed();
        if (pos < flushedPosition) {
            throw new IndexOutOfBoundsException();
        }
        flushedPosition = pos;
    }
    // 获取已刷新位置
    @Override
    public long getFlushedPosition() {
        checkClosed();
        return flushedPosition;
    }
    // 标记当前位置(用于reset)
    @Override
    public void mark() {
        checkClosed();
        markPosition = streamPosition;
    }
    // 重置到标记位置
    @Override
    public void reset() throws IOException {
        checkClosed();
        if (markPosition != -1) {
            seek(markPosition);
            markPosition = -1;
        }
    }
    // 关闭流
    @Override
    public void close() throws IOException {
        checkClosed();
        closed = true;
    }
    // 检查是否关闭
    @Override
    public boolean isClosed() {
        return closed;
    }
    // 检查流状态
    private void checkClosed() {
        if (closed) {
            throw new IllegalStateException("Stream is closed!");
        }
    }
}

实用性方法

public class ImageInputStreamImpl {
    // 读取无符号字节
    @Override
    public int readUnsignedByte() throws IOException {
        return read() & 0xFF;
    }
    // 读取无符号短整数
    @Override
    public int readUnsignedShort() throws IOException {
        return readShort() & 0xFFFF;
    }
    // 读取长整数
    @Override
    public long readLong() throws IOException {
        int hi = readInt();
        int lo = readInt();
        return ((long) hi << 32) | (lo & 0xFFFFFFFFL);
    }
    // 读取浮点数
    @Override
    public float readFloat() throws IOException {
        return Float.intBitsToFloat(readInt());
    }
    // 读取双精度浮点数
    @Override
    public double readDouble() throws IOException {
        return Double.longBitsToDouble(readLong());
    }
}

自定义实现示例

public class ByteArrayImageInputStream extends ImageInputStreamImpl {
    private byte[] data;
    private int length;
    public ByteArrayImageInputStream(byte[] data) {
        this.data = data;
        this.length = data.length;
        this.streamPosition = 0;
    }
    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        checkClosed();
        // 检查边界条件
        if (streamPosition >= length) {
            return -1;  // EOF
        }
        // 计算实际可读字节数
        int available = (int) (length - streamPosition);
        int bytesToRead = Math.min(len, available);
        // 复制数据
        System.arraycopy(data, (int) streamPosition, 
                        b, off, bytesToRead);
        // 更新位置
        streamPosition += bytesToRead;
        return bytesToRead;
    }
    @Override
    public long length() {
        return length;
    }
}

使用示例

public class ImageIOExample {
    public static void main(String[] args) throws IOException {
        // 创建自定义实现
        byte[] imageData = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
        ByteArrayImageInputStream input = 
            new ByteArrayImageInputStream(imageData);
        try {
            // 读取数据
            input.setByteOrder(ByteOrder.BIG_ENDIAN);
            // 读取一个整数值
            int value = input.readInt();
            System.out.println("Read value: " + value);
            // 使用位操作
            input.seek(0);  // 回到开头
            int bits = input.readBits(12);
        } finally {
            input.close();
        }
    }
}

这个基础实现提供了处理图像I/O的所有必要功能,子类只需要实现核心的 read() 方法即可,这种设计使得扩展不同的数据源变得非常简单。

抱歉,评论功能暂时关闭!