Android Tutorial [java] Loading files from a library

Erel

B4X founder
Staff member
Licensed User
Longtime User
The correct way to load files from a library is with anywheresoftware.b4a.objects.streams.File.OpenInput.

anywheresoftware.b4a.objects.streams.File.OpenInput deals correctly with standard files, assets files and virtual assets file (new to v3.50).

Starting from v3.50 the rapid debugger uses a virtual assets folder. This allows the debugger to only redeploy updated files. This means that if you try to directly load a file from the assets file then it will fail.

Calling File.OpenInput will work correctly and will return an InputStream which you can work with.

In some rare cases (sound related APIs for example) the API requires a FileDescriptor. In this case you need to check whether a virtual assets folder is used and then either load the standard file or load the asset file.

For example: SoundPoolWrapper.Load
B4X:
public int Load(String Dir, String File) throws IOException {
     if (Dir.equals(anywheresoftware.b4a.objects.streams.File.getDirAssets())) {
       if (anywheresoftware.b4a.objects.streams.File.virtualAssetsFolder != null) {
         return Load(anywheresoftware.b4a.objects.streams.File.virtualAssetsFolder,
             anywheresoftware.b4a.objects.streams.File.getUnpackedVirtualAssetFile(File));
       }
       return getObject().load(BA.applicationContext.getAssets().openFd(File.toLowerCase(BA.cul)), 1);
     }
     else {
       return getObject().load(anywheresoftware.b4a.objects.streams.File.Combine(Dir, File), 1);
     }
   }
 

FabioC6

Member
Licensed User
Hi Erel,
I'm trying to load a file from dirAssets by using the following code

B4X:
public FileInputStream getb4FIS(String Dir, String File)
{
    AssetFileDescriptor fileDescriptor;
  
    try
    {

        if (Dir.equals(anywheresoftware.b4a.objects.streams.File.getDirAssets()))
        {
            if (anywheresoftware.b4a.objects.streams.File.virtualAssetsFolder != null)
            {
                Dir=anywheresoftware.b4a.objects.streams.File.virtualAssetsFolder;
                File=anywheresoftware.b4a.objects.streams.File.getUnpackedVirtualAssetFile(File);
            }
            else
            {          
                fileDescriptor=BA.applicationContext.getAssets().openFd(File.toLowerCase(BA.cul));
                return fileDescriptor.createInputStream();
            }
        }
      
        return new FileInputStream(anywheresoftware.b4a.objects.streams.File.Combine(Dir, File));
    }
    catch (Exception e)
    {
        BA.Log(e.getMessage());
        e.printStackTrace();
        return null;
    }
}

It works fine in Debug mode, however when running in release i got this error

"This file can not be opened as a file descriptor; it is probably compressed"

What did I do wrong?

Any help with this would be greatly appreciated.
 
Last edited:

FabioC6

Member
Licensed User
I need a FileInputStream, not InputStream,

as far as I know there's no way to convert InputStream to FileInputStream
 
Top