Контекст

Я адаптирую части существующего проекта к проекту gae. В исходном проекте используются FileInputStream и FileOutputStream, но поскольку gae не принимает FileOutputStream, я заменяю их на ByteArrayInputStream и ByteArrayOutputStream. Исходный код загружал некоторые локальные файлы, и я заменил их на Datastore Entities, которые содержат содержимое этих файлов в одном из своих свойств.

Проблема

В основном это работает, но я получаю ArrayIndexOutOfBoundsException в этом фрагменте кода:

private byte[] loadKey(Entity file) {
        byte[] b64encodedKey = null;
        ByteArrayInputStream fis = null;
        try {
            fis = fileToStreamAdapter.objectToInputStreamConverter(file);
            b64encodedKey = new byte[(int) fis.available()];
            fis.read(b64encodedKey);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return b64encodedKey;
    }

fileToStreamAdapter.objectToInputStreamConverter(file) берет Datastore Entity и превращает содержимое одного из своих свойств в ByteArrayInputStream.

Исходный код:

private byte[] loadKey(String path) {
        byte[] b64encodedKey = null;
        File fileKey = new File(path);
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(fileKey);
            b64encodedKey = new byte[(int) fileKey.length()];
            fis.read(b64encodedKey);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return b64encodedKey;
    }

Есть ли что-то, чего мне не хватает в различиях между FileInputStream и ByteArrayInputStream, что могло бы вызвать эту ошибку?

0
LisaMM 13 Мар 2015 в 16:24

2 ответа

Лучший ответ

Мне кажется, что если objectToInputStreamConverter создал ByteArrayInputStream с помощью ByteArrayInputStream (byte [] buf), тогда он может просто вернуть аргумент byte [] и избавить вас от необходимости читать что-либо еще, не говоря уже обо всем этом обработка ошибок.

0
Steve C 13 Мар 2015 в 13:37

fis.available() - это не размер входного потока, а просто количество данных, доступных в буфере на данный момент.

Если вам нужно вернуть байты из входного потока, вы должны скопировать его, используя что-то вроде этого:

ByteArrayOutputStream buffer = new ByteArrayOutputStream();

int l;
byte[] data = new byte[16384];
while ((l = fis.read(data, 0, data.length)) != -1) {
  buffer.write(data, 0, l);
}
buffer.flush();
return buffer.toByteArray();

Или лучше нас IOUtils от commons-io

0
Igor Artamonov 13 Мар 2015 в 13:34