Реализация ImageInputStreamImpl, которая оборачивает byte [] - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь создать реализацию ImageInputStream, которая просто переносит байт [].

Это моя реализация, но для некоторого изображения ImageIO возвращает ошибку о поврежденных данных.

Я могуНе найдено никакой полезной альтернативы, каждый подкласс ImageInputStreamImpl, связанный с JDK, выполняет кэширование и тратит память.

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 голосов
/ 04 декабря 2018

Я столкнулся с аналогичной проблемой и создал реализацию , которая доступна на 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.Но я не думаю, что это имеет большое значение (т.е. я никогда не видел код, который на самом деле использует эти методы для оптимизации чего-либо).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...