Loading...
Logo
Processing Forum
Hi folks,

I am hoping that someone can clarify how to read files from a processing project's data folder on Android. I have the following sample code:

Copy code
  1. import java.io.BufferedReader;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. void setup() {
  5.   BufferedReader br;
  6.   String line;
  7.   try {
  8.      br = new BufferedReader(new FileReader(dataPath("sample.txt")));
  9.      while((line=br.readLine())!=null){
  10.        System.out.println(line);
  11.      }
  12.   } catch (Exception e) {
  13.      System.out.println("IOException when trying to read sample.txt:\n"+e);
  14.      System.exit(0);
  15.   }
  16. }

This works fine when running processing on desktop mode, and it successfully finds and prints out sample.txt. However, when running on the Emulator under Android mode, I get a file not found exception:


IOException when trying to read sample.txt:
java.io.FileNotFoundException: /data/data/processing.test.gpa/files/data/sample.txt (No such file or directory)

Either the problem is that dataPath() is not returning the correct path on Android mode or the files in the data folder are not being transferred correctly. The "/data/data..." part of the pathname looks unusual to me and I'll look at it a bit more later, but I thought I would post something here first. I'm using Processing 2.0.1 with the v10 Android SDK installed. Any ideas?

Thanks

Mike

Replies(1)

Handling files on Android is different to how files are handled on desktop/java systems.

When you run Java version, your [data] is just a subfolder inside of the sketch folder.  That is NOT TRUE with android. 

In androd such concept as "sketch data folder" doesn't really exist.  All files are saved as "resources" of your app. And when you call some file reading method, like:

Copy code
  1. String[] loadStrings("sample.txt"){
  2.    // doing something to ge buffered reader

  3.    ....
  4.    // iterate over strings.
  5.   
  6.   
  7. }

in java it will be translated into:
// doing something to get BufferedReader
new BufferedReader(new FileReader(dataPath("sample.txt")));
and you can see ^^^^ that it does what you expect: just access file from [data] subfolder.





but in Android it will be translated into


// doing something to get BufferedReader
InputStream is = createInput("sample.txt"); // create input fetches file 
                                            // internally from resource
                                  // using getAssetsManager().getResoure()
                                   // in android there's no actual [data]
                                  // folder. files are stored as resources
                                   // and createInput() fetches them from
                                          // there
BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));



What confused you is that dataPath() still worked and returned some path. The thing is that under the hood, all dataPath() is doing is just string concatenation 
Copy code
  1. return sketchPath() + "/data" 
In Android sketchPath() exists. But "data" folder doesn't (as files are stored as app-resources). But dataPath() doesn't really care about it, because it's dumb method which only does concatenation.
Probably it would be better if  dataPath() in Android would either throw an exception or print out warning message saying that you can't really use it on android.

But in the end, for your sketch to work properly in BOTH Java and Android, don't create streams or StreamReaders directly from path, but use createInput() instead.

Copy code
  1. import java.io.BufferedReader;
  2. import java.io.InputStreamReader;
  3. import java.io.IOException;
  4. void setup() {
  5.   BufferedReader br;
  6.   String line;
  7.   
  8.   try {
  9.      InputStream is = createInput("sample.txt");
  10.      br = new BufferedReader(new InputStreamReader(is, "UTF-8"));    
  11.      while((line=br.readLine())!=null){
  12.        System.out.println(line);
  13.      }
  14.   } catch (IOException e) {
  15.      System.out.println("IOException when trying to read sample.txt:\n"+e);
  16.      System.exit(0);
  17.   }
  18. }