# saveStrings() works but it shouldn't - or should it?

**URL:** <https://discourse.processing.org/t/savestrings-works-but-it-shouldnt-or-should-it/3802>\
**Category:** Processing for Android\
**Created:** [September 24, 2018, 5:38pm UTC](https://discourse.processing.org/t/savestrings-works-but-it-shouldnt-or-should-it/3802 "2018-09-24T17:38:33Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dtmr](https://avatars.discourse-cdn.com/v4/letter/d/4da419/32.png) [@dtmr](https://discourse.processing.org/u/dtmr)\
**Post date:** [September 24, 2018, 5:38pm UTC](https://discourse.processing.org/t/savestrings-works-but-it-shouldnt-or-should-it/3802/1 "2018-09-24T17:38:33Z")

</div>

My app, which was originally programmed for Windows, uses loadStrings() and saveStrings() to save its settings. Under Processing for Android, I would have expected that saveStrings() doesn’t work (after reading [https://forum.processing.org/one/topic/how-to-savestrings-in-android-22-8-2013.html](https://forum.processing.org/one/topic/how-to-savestrings-in-android-22-8-2013.html)). Except that it does?! Is this a recent feature or does writing only work on the emulator?

```auto
LoadConfig()
{
    File filehandle = new File(sketchPath("config.txt"));
    
    println("PATH "+ sketchPath("config.txt"));
      
    if (filehandle.exists()) 
    {  
        String config[] = loadStrings("config.txt");

        ...
    }
}

void
SaveConfig()
{
    String config[] = new String [1];

    config[0] = ...;
    
    saveStrings("config.txt", config);
}

```

The println() command to display where the data ends up says “/data/user/0/com.myname.testapp/files/config.txt”. I can not browse to that location on the emulator and I don’t find my settings file anywhere else. For example, not under /storage/emulated/…

---

<div class="post-metadata">

**Author:** ![kfrajer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kfrajer/32/196_2.png) [@kfrajer](https://discourse.processing.org/u/kfrajer)\
**Post date:** [September 24, 2018, 9:15pm UTC](https://discourse.processing.org/t/savestrings-works-but-it-shouldnt-or-should-it/3802/2 "2018-09-24T21:15:41Z")

</div>

You cannot reach this location as it is an internal storage attached to your application, so i understand from the documentation. If you want to get access to any file that you save from your app, you need to save them using getExeternalStorage (don’t forget to enable the permissions) and you need to use absolute paths when working with saveStrings and loadStrings. You get the absolute path using the same getExternalStorage function, as you have seen in previous posts.

Related to your initial question, saveStrings() works as it uses the location of `sketchPath()` instead of `dataPath()` internally. I believe Andres made a recent change so when loading data, Android mode will first, attempt to get the data using the folder location provided by `dataPath()`. If that fails, it automatically looks into `sketchPath()`. It might throw a warning when it does this… This is an attempt to try to keep `dataPath()` functionality aligned to the Processing java counterpart.

Kf

---

<div class="post-metadata">

**Author:** ![akenaton](https://avatars.discourse-cdn.com/v4/letter/a/a88e4f/32.png) [@akenaton](https://discourse.processing.org/u/akenaton)\
**Post date:** [September 25, 2018, 2:30pm UTC](https://discourse.processing.org/t/savestrings-works-but-it-shouldnt-or-should-it/3802/3 "2018-09-25T14:30:06Z")

</div>

@dtmr,@kfrajer ====  
Globally, android storage can be of 3 types:

- internal storage (that is inside your app)
- external storage inside the phone memory
- external storage sd card

normally for little files (like scores in a game and so on, perhaps your config file) you saved them using the internal storage, which is the default one; you can see the path to it with context.getFilesdir().getAbsolutePath(); as for rwriting you can use FileOutPutStream adding either context\_MODE-PRIVATE or Context.MODE\_APPEND; with the second one you can add things to your file; with the first you delete the whole content when you save.

In order to read your files you can use either FileInputStream or processing loadStrings() using the path to your internal storage.

for files more important (videos, sounds…) using external storage is better and as kfrajer said you get the path with getExternalStorage().getAbsolutePath();

in your case i think that you have to save inside onPause();

---

<div class="post-metadata">

**Author:** ![dtmr](https://avatars.discourse-cdn.com/v4/letter/d/4da419/32.png) [@dtmr](https://discourse.processing.org/u/dtmr)\
**Post date:** [October 5, 2018, 6:12pm UTC](https://discourse.processing.org/t/savestrings-works-but-it-shouldnt-or-should-it/3802/4 "2018-10-05T18:12:09Z")

</div>

> you can use … loadStrings()

So reading/writing internal storage is easy - loadStrings() and saveStrings(). But how can a file be copied from external storage (e.g. download directory) to internal storage? Saving to internal storage isn’t the problem, that’s just saveStrings() with an argument that has no path part. However, loadStrings() with a fully qualified path fails: “Java.lang.IllegalArgumentException: File … contains a path separator”. Should that happen or is that a bug? Documentation states absolute paths - outside data directory - are allowed. Permissions for external storage were set.

```auto

// copy file specified by <filename> from downloads to internal storage

String PathDownload = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();

File handle = new File(PathDownload + File.separator + filename);
        
if (handle.exists())
{
    // next line throws exception "contains path separator"

    String strings[] = loadStrings(handle.toString());
        
    ...    
    
    saveStrings(filename, strings);
}

```

---

<div class="post-metadata">

**Author:** ![akenaton](https://avatars.discourse-cdn.com/v4/letter/a/a88e4f/32.png) [@akenaton](https://discourse.processing.org/u/akenaton)\
**Post date:** [October 6, 2018, 1:37pm UTC](https://discourse.processing.org/t/savestrings-works-but-it-shouldnt-or-should-it/3802/5 "2018-10-06T13:37:02Z")

</div>

@dtmr===  
that s not a bug && the error is well explicated: a file name never includes a path separator.

solution is easy (there are many others, using fileInputStream for example, which is more evident to understand than the wrapper loadStrings() P5 is using). So, supposing that you want to loadStrings from the externalStorageDirectory (the same for download dir) and supposing that the file is called “essai.txt”:

```auto
File externalDir = Environment.getExternalStorageDirectory();
   File[] files = externalDir.listFiles();
   String path = externalDir.getAbsolutePath();
   println(path);
 printArray(files);//here you can see all the files and as they are in an array you can also directly get one:
Strings[] monFichier= files[somenumber];//some number= you have seen in the printArray or you can get it by code with a loop
 String[] fichier= loadStrings(path+"/"+"essai.txt");//not any error is fired
 println(fichier[0]);

```
