包装byte []的ImageInputStreamImpl实现

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (103)

我正在尝试创建一个ImageInputStream的实现,它只包含一个byte []。

这是我的实现,但对于某些图像,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”方法来修改内部流位置。

提问于
用户回答回答于

我曾经遇到类似的问题,并且已经创建了一个实现了可在GitHub下BSD许可证。而不是包装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。但我认为这并不重要(即我从未见过实际使用这些方法来优化任何东西的代码)。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励