Необходимо преобразовать AssetInputStream в FileInputStream

Я реализовал структуру данных, которая работает на моем компьютере, и теперь я пытаюсь перенести ее в свое приложение для Android. Я открываю необработанный .dat ресурс и получаю InputStream, но мне нужно получить FileInputStream:

FileInputStream fip = (FileInputStream) context.getResources().openRawResource(fileID);
FileChannel fc = fip.getChannel();
long bytesSizeOfFileChannel = fc.size();
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0L, bytesSizeOfFileChannel);
...

Приведенный выше код вызывает следующее исключение, поскольку InputStream не может быть преобразован в FileInputStream, но это как раз то, что мне нужно:

java.lang.ClassCastException: android.content.res.AssetManager$AssetInputStream cannot be cast to java.io.FileInputStream

Весь мой код построен на использовании этого FileChannel с FileInputStream, поэтому я хочу продолжать его использовать. Есть ли способ перейти от InputStream к context.getResources().openRawResource(fileID), а затем преобразовать его в FileChannel?


В некоторой степени релевантные сообщения, в которых я не смог найти рабочего решения для моего случая, какой android:

Как преобразовать InputStream в FileInputStream

Преобразование inputStream в FileInputStream?

Использование FileChannel для записи любого InputStream?



person Joop    schedule 09.05.2015    source источник
comment
нет, файлы ресурсов не являются обычными файлами, то есть они не существуют в файловой системе   -  person pskink    schedule 09.05.2015
comment
Я работал над этим 2 недели. Если я не смогу заставить это работать, я буду смеяться еще как минимум 2 недели.   -  person Joop    schedule 09.05.2015
comment
почему вы не можете просто использовать InputStream?   -  person pskink    schedule 09.05.2015
comment
Вся моя цель состояла в том, чтобы создать структуру данных, которая была бы настолько быстрой, насколько это было возможно в Java. Или, по крайней мере, в меру моих способностей. Я прочитал эту статью nadealesoftware.com/artic2/artic2/artic2/artic2/artic что метод, который я использую, самый быстрый. Вот почему я реализовал это таким образом.   -  person Joop    schedule 09.05.2015
comment
В лучшем случае в статье говорится, что использование MappedByteBuffer для JVM Java 6 является быстрым при чтении файла. Android не использует Java 6 JVM, и вы не читаете файл. Android запускает либо виртуальную машину Dalvik, либо использует ART (в зависимости от версии Android), и вы читаете ресурс (который в основном представляет собой запись в ZIP-файле). Содержание этой статьи не имеет отношения к делу.   -  person CommonsWare    schedule 09.05.2015
comment
Справедливые баллы. Жаль, что мне потребовалось 2 недели, чтобы это выяснить.   -  person Joop    schedule 09.05.2015


Ответы (2)


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

person user207421    schedule 09.05.2015

Это может быть поздно, но я думаю, что вы можете косвенно получить FileInputStream из InputStream. Я предлагаю следующее: получить входной поток из ресурса, затем создать временный файл, получить из него FileOutputStream. прочтите InputStream и скопируйте его в FileOutputStream.

теперь временный файл содержит содержимое вашего файла ресурсов, и теперь вы можете создать FileInputStream из этого файла.

Я не знаю, полезно ли вам это конкретное решение, но думаю, что его можно использовать в других ситуациях. Например, если ваш файл находится в папке с ресурсами, вы получите InputStream, а затем FileInputStream, используя этот метод:

InputStream is=getAssets().open("video.3gp");
File tempfile=File.createTempFile("tempfile",".3gp",getDir("filez",0));

FileOutputStream os=newFileOutputStream(tempfile);
byte[] buffer=newbyte[16000];
int length=0;
while((length=is.read(buffer))!=-1){
os.write(buffer,0,length);
}

FileInputStream fis=new FileInputStream(tempfile);
person vikrant    schedule 08.05.2016