Получение неправильного размера FileChannel

Я пытаюсь получить размер файла, содержащегося в assets. Я использую FileChannel, потому что мне нужно FileChannel позже. Файл myfile.txt содержит 7 байтов.

Вот мой код:

AssetManager amgr;
AssetFileDescriptor afd;
FileChannel fchIn;
FileInputStream fis;

amgr=context.getAssets();
afd=amgr.openFd("myfile.txt");
fis=afd.createInputStream();
fchIn=fis.getChannel();

Log.d("mytag", fchIn.size());
Log.d("mytag", fis.available());

И результат:

7237492
7

Почему размер, возвращаемый методом FileChannel.size(), неверный?

Спасибо за помощь

Ответ 1

FileInputStream.getChannel() документация говорит, что он "Возвращает FileChannel только для чтения, который разделяет свою позицию с этим потоком". Вы предполагаете, что канал начинается и заканчивается точно в границах вашего файла, что является единственным способом, чтобы его итоговый size() соответствовал ожидаемому, но документация не гарантирует эту гарантию.

Также обратите внимание, что FileInputStream.available() не документировано означает то же самое, что и общий размер - технически, это объем данных, доступных для чтения, без необходимости загружать/буферировать больше из источника. Если весь источник уже не был прочитан в память, он может практически не иметь никакого отношения к фактическому размеру файла.

Я ожидаю, что базовый FileChannel имеет доступ к большому диапазону байтов для нескольких файлов, как и все ваши активы, объединенные (и, следовательно, большой размер), и вам нужно будет ссылаться на AssetFileDescriptor getStartOffset() и getLength(), чтобы узнать фактическое положение связанных байтов файла в канале. Я предполагаю, что AssetFileDescriptor.createInputStream() дает вам объект, который уже знает позицию и диапазон, и заботится об этом для вас. Если вы собираетесь использовать необработанный канал, то почитайте информацию в дескрипторе файла. Также обратите внимание, что в документации, если вы перемещаете позицию FileInputStream (например, путем чтения байтов), вы также перемещаете позицию канала одновременно, поэтому будьте осторожны, если вы пытаетесь использовать оба.