0

I'm trying to store my Properties-Object and load it again.
There is no exception on storing, but when I try to load and read it, it seems to be empty.

Here you have the code i'm using to store:

public class mainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //[...]
    private String filename = "config.properties"; //config-savePath
    private HashMap<String, String> someMap= new HashMap<>(); 
    someMap.put("SOME_KEY", "myValue");

    try{  //try to store and log (seems to work)
        Properties properties = new Properties();
        properties.putAll(someMap);

        Log.v("===INFO===","List all Properties:");
        for (String key : properties.stringPropertyNames()) {
                Log.v("===INFO===","Property :" + key + " = " + properties.get(key).toString());
        }

        properties.store(getAssets().openFd(filename).createOutputStream(), null);
        Log.v("===INFO===","storing information successfully");
    }catch (IOException e){
        Toast.makeText(this,"- Error -\n information could not be stored",Toast.LENGTH_SHORT).show();
        Log.v("===ERR===", "Cert-Info could not be stored -fileNotFound-" + e.toString());
    }

Here you have the code I'm using to load (for Dev-reasons I execute it directly after storing):

    try{  //try to load and log
        Log.v("===INFO===","Try loading Properties after storing");
        Properties properties = new Properties();
        properties.load(getBaseContext().getAssets().open(filename,Context.MODE_PRIVATE));

        if (properties.isEmpty()){
            Log.v("===ERR===", "Properties is empty");
        }else{
            for (String key : properties.stringPropertyNames()) {
                Log.v("===INFO===","Property :" + key + " = " + properties.get(key).toString());
            }
        }
    }catch (IOException e){
        Log.v("===ERR===", "Properties could not be loaded" + e.toString());
        e.printStackTrace();
    }
}}//end oncreate //end class

When I execute the code I get these Logs:

09-19 15:01:18.172 31242-31242/com.example.myapplication V/===INFO===: List all Properties:
09-19 15:01:18.173 31242-31242/com.example.myapplication V/===INFO===: Property :SOME_KEY = myValue
09-19 15:01:18.176 31242-31242/com.example.myapplication V/===INFO===: storing information successfully
09-19 15:01:18.176 31242-31242/com.example.myapplication V/===INFO===: Try loading Properties after storing
09-19 15:01:18.177 31242-31242/com.example.myapplication V/===ERR===: Properties is empty

So as you can see, the loaded Property is empty. I have no idea why.
I would expect something like this instead of the error:

09-19 15:01:18.177 31242-31242/com.example.myapplication V/===INFO===: Try loading Properties after storing
09-19 15:01:18.178 31242-31242/com.example.myapplication V/===INFO===: Property :SOME_KEY = myValue

It doesn't work, and was not able to find a compareable problem here.

If you like to copy and paste my code to androidStudio, please do the necessary Imports (auto-gen) and add a "assets"-folder with a "config.properties"-file to your Project-directory. Hope you guys can help me!

EDIT: I`ve placed a config.properties File with content in the assets-Folder. Now Loading works fine, but I recive this error on storing:

java.io.IOException: write failed: EBADF (Bad file descriptor)
Tetrick
  • 1
  • 2
  • Welcome to Stack Overflow. We can help you more quickly if you provide a [mcve]. You should provide enough code that anyone can copy/paste and then compile and run your code and get the exact same results which you are asking about. – Code-Apprentice Sep 19 '17 at 14:02
  • The code is already a minimal complete snippet. A c+p is possible, if the user does the suggessted imports, creats the "asserts" directory an the "config.properties" File in there. – Tetrick Sep 19 '17 at 14:43
  • The code you here gives compile errors because there is no class. Therefore, it is not complete. – Code-Apprentice Sep 19 '17 at 17:09
  • oh I'm sorry. You are right. I enjoy the compfort of AndroidStudio where you will get a prepared class =). I will edit the post for you =) – Tetrick Sep 20 '17 at 07:14

2 Answers2

1
  HashMap<String, String> mymap = new HashMap<String, String>();

Option 1:
     Properties prop = new Properties();
     prop.setProperty("SOME_KEY", "myValue");


Option2 :
     mymap.put("1", "test");
     mymap.put("2", "test2");
     prop.putAll(mymap);
     prop.store(new FileOutputStream("config.properties"),"");


Please refer to following link
    https://www.mkyong.com/java/java-properties-file-examples/
Pradeep
  • 1,947
  • 3
  • 22
  • 45
  • I don't think that that is an error: If I'm not totaly wrong i can set multiple properties from a HashMap by using `prop.putAll(someHashMap)` As you can see in the log-file, the properties-object contains the key-value-pair correctly before storing. or did you mean s.th. else? – Tetrick Sep 19 '17 at 13:32
  • Update my answer please cross check – Pradeep Sep 19 '17 at 14:01
  • **Option 1** is not relevant for my app, and has no impact on my problem. **Option 2** will give an `java.io.FileNotFoundException: config.properties: open failed: EROFS (Read-only file system)` exception because in android Properties have to be accessed via `getAssets().openFd(filename).createOutputStream()` **refer link** -I found this link too, i going to try it if nobody can say why my try does not work. **Anyway** I'm realy grateful that you try to help me – Tetrick Sep 19 '17 at 14:36
  • Hi Terik You need to give the path of config properties where you have in your machine like assume you have kept that file in c:\\temp\\config.properties if you are using in your project then you can use class loader to load from project – Pradeep Sep 19 '17 at 15:19
  • `getAssets().openFd("config.properties").createOutputStream()` should return a FileOutputStream on the path of the file (look at https://stackoverflow.com/a/35075814/8633513) - The path don't seems to be the problem because in that case would get an exeption. – Tetrick Sep 20 '17 at 07:46
  • hi Terick I tried the snippet in my eclipse ,post that only I gave the solution.Can you debug and see whether config.properties are getting loaded properly – Pradeep Sep 20 '17 at 07:48
  • Basically your code should look similar to this http://crunchify.com/java-properties-file-how-to-read-config-properties-values-in-java/ – Pradeep Sep 20 '17 at 07:50
  • Okay I'm pretty sure now that it is an problem on the android file-system (the assets-folder my be not writeable?) - a self-written .properties file can be loaded sucessfully. Now the write operation thrwos an error. I will update the question. – Tetrick Sep 20 '17 at 12:43
0

After some research I could figure out the problem. It is depending on the "Asserts"-Folder - it is a simple Read-Only-problem. Answered here: Is Asset folder read-only?

This is why "load" works fine, but "store" does not. It seems that there is no exception thrown if you try to write to an empty .property file, even if it should (it won't work either).

A common work-around is using the Internal Storage instead of the asserts-folder.

Tetrick
  • 1
  • 2