Is it safe to read Android asset file with FileChannel? - android

I need to read binary file from asset folder in my app, and the way I'm trying to do it is by obtaining Channel:
AssetFileDescriptor assetFd = context.getAssets().openFd("file.db");
FileChannel fileChan = assetFd.createInputStream().getChannel();
The problem is that AssetManager, AssetFileDescriptor are very poorly documented classes and behave in unpredicted manner (as it seems to me). For example, if you will try to obtain fileChan.position() immediately after code above you won't get 0, in my case it'll be 976. After digging through StackOverflow I found out that it's normal behaviour and you need to be aware that assets are compressed into some internal binary form and AssetFileDescriptor isn't real file descriptor.
In my case I have a file structure with absolute byte positions stored in a header, so it seems like to read it properly I also need take into account assetFd.getStartOffset().
Also I've got zero clue about method AssetFileDescriptor.createInputStream behaviour after reading its doc:
This will either return a full asset AssetFileDescriptor.AutoCloseInputStream, or an underlying ParcelFileDescriptor.AutoCloseInputStream depending on whether the the object represents a complete file or sub-section of a file.
Lack of understanding whole picture and documentation makes me nervous about using this approach.
Should I be worried about AssetFileDescriptor.createInputStream behaviour when reading big files (over 1mb)? Is it safe to use Channels when reading asset files?
Thank you in advance!

The best way to deal with assets is to copy them to the internal or external storage and then read them with whatever method you want.
Thanks to #pskink for help!

Related

Unknown JPEG compression technique?

Well, so I've been digging through an android game's files trying to get sprites and the like. So I've managed to come across this folder called "raw", and inside were jpg files like imagelocal2.jpg (along with imagelocal2.list) and such. These files aren't valid images and can't be viewed normally, but they're big enough to contain many images inside of them.
What I'm wondering is, is there some unknown JPG compression-like method where they manage to squish a bunch of files into one? I opened the files with a hex editor but I couldn't make heads or tails of them (the fact that I have no experience with hex editors doesn't really help), so if anyone knows anything about how these files are compressed, please help.
There is no standard multi-image JPEG format. it would be anything with a JPG extension. No competently-written decoder would rely on the extension anyway.
You could take a look at the first few bytes and try to match the file signature.
http://en.wikipedia.org/wiki/List_of_file_signatures

how to determine the extension of a file

I'm fetching byte array from server but don't know the exact extension of the file because that file could be .pdf / mp4 / docx / zip, so how would I know the exact extension after saving it to sdcard.
Any idea?
There's no way to reliably determine the file extension from the file contents. It's like trying to find out what was written on an envelope, if all you have is the letter itself.
You could guess, but that would be a difficult task (for example, a docx is also a zip file). There is specialized software for this (many operating systems include the file tool), and you might find a third-party library that you can use, but even if you do that, it's still a guess.
I'd rather concentrate on finding a way for the server to tell you the original file name in addition to the contents.
There is no proper way to determine the file extension right away.
However you can impose conditions for the specific file types like if the file extension is mp3 then do the certain task. For that you can use FilenameFilter.
Check the how-to-find-all-files-with-certain-extension-on-android for more information about it.
If it is custom protocol, you should pass one(or more) byte of data type to the client side, then you get data and add extension on the client side according to the first byte(s). If it is http-like protocol, you can add some header to the answer. But it is need to do as on the serverside as well as on the clientside too.

Android 2.2: best way to read small blocks of binary data from big files?

I'm developing for Android 2.2.
Things put to res and assets are compressed in the APK by default unless their extension indicates that they're already compressed (mp3, png). Moreover, before Android 2.3, to assets, you could only put uncompressed files of size less than 1 MB.
Question 1:
if I put a 1.5MB binary file to res/raw, and my program refers to it with its standard Android ID (R.raw.....), then will the system pull the whole file into memory? Since the 1.5MB is stored in a compressed way, I suppose it must. This is unpleasant because it is possible that the program only needs 1KB of data to be loaded from a given file offset. This can have a serious impact on app performance/speed.
I see two solutions:
(hack) Use mp3 or png extensions; but I am not sure this allows memory-efficient access after all (i.e. inputstream.skipbytes, etc.)
After the installation, at the first start of the app, the app will copy the files to its own writable working folder (in SD card). Since this point, it will always access the files from there instead of the R.raw... way. Therefore, the sequential read will work for sure, i.e. the memory usage will be no more than the actual data read from the specified file offset (apart from temporary read buffers used by inputstream.seek implementation, which are well-optimized i.e. small I suppose).
Question 2:
what is the best way of reading binary data memory-efficiently, from big files? I don't want to split my big files into many small ones unless that's the only way.
I'd go with #2 solution and then would use RandomAccessFile to avoid linear access.
I also would to opt for solution #2, but instead of using random access file, I would use java.nio.MappedByteBuffer - this way you will get fast random access with byte buffer semantic.

Android writing to a text file

I have a text file within my raw folder of my app that I intend to use as a simple way to save settings and then read them back when needed. I can read from this file with using the BufferedReader and what comes with it, but I've tried a few different ways to be able to write to this file and none seem to work.
It seems to me that the problem is I never actually get the file, and I assume this is simply because I don't exactly know how I am supposed to give it the correct directory and file name. I've tried all I could come up with, and I tend to get errors like "No such file or directory exists" or "Read-only file system".
This seems to be a very simple problem relating to me just giving the wrong information, so if anybody could point me in the right direction it would be much appreciated.
Thank you,
Raphy
For saving settings you should use SharedPreferences rather than coming up with a custom solution.
SharedPreferences documentation
Data Storage
I'm not entirely sure you can do that with stuff in the "raw" folder.
One approach would be to use the SharedPreference storage in the API. See in the datastorage section of the docs. It's perfect from what you describe neededing. Another approach would be to put the file on the SDCard and read and write it from there.

read an image I just wrote in android

So, largely for debugging purposes, I want to be able to write an image at arbitrary points in my code, and look at it later. I figured this would be easiest if I just wrote a my bitmap to a file and read it back later, but I cannot seem to figure out where to find the file after I write it, or how to open an image that is not in res/drawable with a corresponding handle in R.
You can use openFileOutput() and openFileInput(). These pull up data streams that point to files in your app's directory, and are (as far as I know), the suggested way to handle files that your app makes.

Categories

Resources