本文目录导读:

我将为你详细解析 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() 方法即可,这种设计使得扩展不同的数据源变得非常简单。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播