简体   繁体   中英

Load a file from assets folder in android studio

I was wondering if there is a way to access a file and it's path from my assets folder in android studio? The reason why I need to access the file and its path is because I am working with a method that REQUIRES the String path for a file, and it must access the file from its String path. However, in android studio I haven't found a way to access the file directly from the String value of its path. I decided to use a workaround and simply read the file from an InputStream and write the file to an OutputStream, but the file is about 170MB, and it is too memory intensive to write the File to an OutputStream. It takes my application about 10:00 Minutes to download the file when I implement that strategy. I have searched all over this website and numerous sources to find a solution (books and documentation) but am unable to find a viable solution. Here is an example of my code:

@Override
public Model doInBackground(String... params){
        try {
            String filePath = context.getFilesDir() + File.separator + "my_turtle.ttl";
            File destinationFile = new File(filePath);
            FileOutputStream outputStream = new FileOutputStream(destinationFile);
            AssetManager assetManager = context.getAssets();
            InputStream inputStream = assetManager.open("sample_3.ttl");


            byte[] buffer = new byte[10000000];
            int length = 0;
            while ((length = inputStream.read(buffer)) != -1) {
                  outputStream.write(buffer, 0, length);
           }
            outputStream.close();
            inputStream.close();
            model = ModelFactory.createDefaultModel();

            TDBLoader.loadModel(model, filePath, false);//THIS METHOD REQUIRES THE FILE PATH. 
            MainActivity.presenter.setModel(model);

        }catch(FileNotFoundException e){
            e.printStackTrace(System.out);
        }
        catch(IOException e){
            e.printStackTrace(System.out);
        }
        return model;
    }

As you can see the TDBLoader.loadModel() method requires a String for the file URI as the second argument, so it would be convenient to have the ability to access the File directly from my assets folder without utilizing an InputStream. The method takes as an argument (Model model, String url, Boolean showProgress). As I mentioned, the current strategy I am using utilizes too much memory and either crashes the Application entirely, or takes 10 minutes to download the file I need. I am using an AsyncTask to perform this operation, but due to the length of time required to perform the task that kind of defeats the purpose of an AsyncTask in this scenario.

What further complicates things is that I have to use an old version of Apache Jena because I am working with Android Studio and the official version of Apache Jena is not compatible with android studio. So I have to use a port that is 8 years old which doesn't have the updated classes that Apache Jena offers. If I could use the RDFParser class I could pass an InputStream, but that class does not exist in the older version of Apache Jena that I must use.

So I am stuck at this point. The method must utilize the String url path of the file in my assets folder, but I don't know how to access this without writing to a custom file from an InputStream, but writing to the file from the InputStream utilizes too much memory and forces the App to crash. If anyone has a solution I will greatly appreciate it.

Here is an example of my code

new byte[10000000] may fail, as you may not have a single contiguous block of memory that big. Plus, you might not have that much heap space to begin with. Use a smaller number, such as 65536.

It takes my application about 10:00 Minutes to download the file when I implement that strategy

The time will vary by hardware. I would not expect it to be that slow on most devices, but it could be on some.

I was wondering if there is a way to access a file and it's path from my assets folder in android studio?

You are running your app on Android. Android Studio is not running on Android. Assets are not files on the Android device. They are entries in the APK file, which is basically a ZIP archive. In effect, your code is unZIPping 170MB of material and writing it out to a file.

If anyone has a solution I will greatly appreciate it.

Work with some people to port over an updated version of Jena that offers reading RDF from an InputStream .

Or switch to some other RDF library.

Or work with the RDF file format directly.

Or use a smaller RDF file, so the copy takes less time.

Or download the RDF file, if you think that will be preferable to copying over the asset.

Or do the asset-to-file copying in a foreground JobIntentService , updating the progress in its associated Notification , so that the user can do other things on their device while you complete the copy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM