ImageInputStreamImpl实现,该实现包装一个字节[]

时间:2018-12-03 15:55:52

标签: java javax.imageio

我正在尝试创建ImageInputStream的实现,该实现只包装一个字节[]。

这是我的实现,但是对于某些映像,ImageIO返回有关损坏的数据的错误。

我找不到任何有用的替代方法,与JDK捆绑在一起的ImageInputStreamImpl的每个子类都执行缓存和浪费内存。

public static class MyMemoryCacheImageInputStream extends ImageInputStreamImpl {

        private SimpleByteArrayInputStream stream;

        public MyMemoryCacheImageInputStream(SimpleByteArrayInputStream stream) {
            if (stream == null) {
                throw new IllegalArgumentException("stream == null!");
            }
            this.stream = stream;
        }

        @Override
        public int read() throws IOException {
            bitOffset = 0;
            return stream.read();
        }

        @Override
        public void seek(long pos) throws IOException {
            super.seek(pos);
            stream.seek(pos);
        }

        @Override
        public int read(byte[] b, int off, int len) throws IOException {
            if (b == null) {
                throw new NullPointerException("b == null!");
            }
            if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
                throw new IndexOutOfBoundsException("off < 0 || len < 0 || off+len > b.length || off+len < 0!");
            }

            bitOffset = 0;

            if (len == 0) {
                return 0;
            }

            return stream.read(b, off, len);
        }

        @Override
        public boolean isCached() {
            return false;
        }

        @Override
        public boolean isCachedFile() {
            return false;
        }

        @Override
        public boolean isCachedMemory() {
            return false;
        }

        @Override
        public void close() throws IOException {
            super.close();
            stream = null;
        }
    }

请注意,SimpleByteArrayInputStream本质上是一个ByteArrayInputStream,具有“ seek”方法来修改内部流的位置。

1 个答案:

答案 0 :(得分:0)

我也面临着类似的挑战,并且创建了implementation,该代码在BSD许可下可在GitHub上使用。无需包装ByteArrayInputStream,它可以直接与byte数组一起使用。

我尚未测试您的实现,但是我相信它的主要问题在于,在阅读时它无法正确更新streamPos。当您调用super.seek(pos)时,查找似乎可以。以下应解决该问题:

@Override
public int read() throws IOException {
    bitOffset = 0;

    int val = stream.read();

    if (val != -1) {
        streamPos++;
    }

    return val;
}

@Override
public int read(byte[] b, int off, int len) throws IOException {
    if (b == null) {
        throw new NullPointerException("b == null!");
    }
    if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
        throw new IndexOutOfBoundsException("off < 0 || len < 0 || off+len > b.length || off+len < 0!");
    }

    bitOffset = 0;

    if (len == 0) {
        return 0;
    }

    int read = stream.read(b, off, len);

    if (read > 0) {
        streamPos += read;
    }

    return read;
}

我还相信,严格来说,isCached()isCachedMemory应该返回true用于实现,如果它确实由byte数组支持。但我认为这没什么大不了的(即,我从未见过实际使用这些方法来优化任何内容的代码)。