24

I have a text file in the assets folder that I need to turn into a File object (not into InputStream). When I tried this, I got "no such file" exception:

String path = "file:///android_asset/datafile.txt";
URL url = new URL(path);
File file = new File(url.toURI());  // Get exception here

Can I modify this to get it to work?

By the way, I sort of tried to "code by example" looking at the following piece of code elsewhere in my project that references an HTML file in the assets folder

public static Dialog doDialog(final Context context) {
WebView wv = new WebView(context);      
wv.loadUrl("file:///android_asset/help/index.html");

I do admit that I don't fully understand the above mechanism so it's possible that what I am trying to do can't work.

Thx!

I Z
  • 5,719
  • 19
  • 53
  • 100
  • Why do you want to read it into a File object? I believe you need to grab the data from the asset as an InputStream and write it out as an outputStream that points to a physical location. Then you can open it up as a File object. http://stackoverflow.com/questions/4447477/android-how-to-copy-files-in-assets-to-sdcard – Gophermofur May 01 '12 at 19:19
  • I am trying to avoid making copies of the asset file, but I'll do it if all else fails. The reason I need a File is that it's used as an argument in a ctor whose code I don't have access to, and that's the only ctor that exists for that class. – I Z May 01 '12 at 19:26
  • Ah, that makes sense. Maybe: Make the copy onto the SDCARD, pass it in \to the constructor and delete it once you're done? If the file is the same and you always save it to the same location on the SDCARD you'd only be making 1 copy (it would just overwrite the previous version). – Gophermofur May 01 '12 at 20:02

3 Answers3

29

You cannot get a File object directly from an asset, because the asset is not stored as a file. You will need to copy the asset to a file, then get a File object on your copy.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 18
    Yes so how do you do that? – Mark Molina Jul 14 '14 at 14:52
  • 1
    @MarkMolina: See the other answer. It's pretty much just standard Java I/O, using an `InputStream` from the `open()` method on `AssetManager`, then copying data from the `InputStream` to an `OutputStream` for your desired file. – CommonsWare Jul 14 '14 at 22:32
13

You cannot get a File object directly from an asset.

First, get an inputStream from your asset using for example AssetManager#open

Then copy the inputStream :

    public static void writeBytesToFile(InputStream is, File file) throws IOException{
    FileOutputStream fos = null;
    try {   
        byte[] data = new byte[2048];
        int nbread = 0;
        fos = new FileOutputStream(file);
        while((nbread=is.read(data))>-1){
            fos.write(data,0,nbread);               
        }
    }
    catch (Exception ex) {
        logger.error("Exception",ex);
    }
    finally{
        if (fos!=null){
            fos.close();
        }
    }
}
Laurent B
  • 2,200
  • 19
  • 29
-1

This function missing in code. @wadali

private void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while((read = in.read(buffer)) != -1){
      out.write(buffer, 0, read);
    }
}

Source: https://stackoverflow.com/a/4530294/4933464

Community
  • 1
  • 1
Mehmet Hanoğlu
  • 2,942
  • 1
  • 13
  • 19