Search code examples
androidfile-ionullpointerexceptionspecial-characters

Unwanted Special Characters added to Android Save File


I think I have a rough idea what the problem is, but not entirely sure. Had a search for a similar solution but only answers for C.

I am writing a list of string values to an internal storage file.

        OUTSTREAM = saveName.toString() + "," +
                d3S.getText().toString() + "," + d3M.getText().toString() + "," + d3C.isChecked() + "," +
                d4S.getText().toString() + "," + d4M.getText().toString() + "," + d4C.isChecked() + "," +
                d6S.getText().toString() + "," + d6M.getText().toString() + "," + d6C.isChecked() + "," +
                d8S.getText().toString() + "," + d8M.getText().toString() + "," + d8C.isChecked() + "," +
                d10S.getText().toString() + "," + d10M.getText().toString() + "," + d10C.isChecked() + "," +
                d12S.getText().toString() + "," + d12M.getText().toString() + "," + d12C.isChecked() + "," +
                d20S.getText().toString() + "," + d20M.getText().toString() + "," + d20C.isChecked() + "," +
                d100S.getText().toString() + "," + d100M.getText().toString() + "," + d100C.isChecked() + "," +
                dCustS.getText().toString() + "," + dCustND.getText().toString() + "," + dCustM.getText().toString() + "," + dCustC.isChecked();

    Log.d("OUTSTREAM::", "" + OUTSTREAM + ";");
    Log.d("OUTSTREAM Bytes::", "" + OUTSTREAM.getBytes() + ";");

        FileOutputStream fos;
        try {
            fos = openFileOutput(FILENAME, Context.MODE_APPEND); //MODE_APPEND MODE_PRIVATE
            fos.write(OUTSTREAM.getBytes());
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(MainActivity.this, "Save FileNotFoundException",Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(MainActivity.this, "Save IOException",Toast.LENGTH_SHORT).show();
        }

LogCat:

08-13 11:33:12.486: D/OUTSTREAM::(1547): NewSave,1,0,true,1,0,true,1,0,true,1,0,true,1,0,true,1,0,true,1,0,true,1,0,true,1,5,0,true;
08-13 11:33:12.486: D/OUTSTREAM Bytes::(1547): [B@52a6507c;

But when I write to file, my data gets additional special characters added to the end of the file.

        try{
         fIn = openFileInput("DiceSaves.txt");
         isr = new InputStreamReader(fIn);
         isr.read(inputBuffer);
         data = new String(inputBuffer);
         Toast.makeText(MainActivity.this, "Loaded: " + data, Toast.LENGTH_SHORT).show();


         List<String> lines = Arrays.asList(data.split("\n"));
         Object[] aLinesArray = lines.toArray();

         String[] SaveNames = new String[10];
         int n = 0;

         for(int i = 0; i < aLinesArray.length ; i++){
             String line = aLinesArray[i].toString();
             Log.d("i and Line::", "" + i + "," + line + ";");

LogCat:

08-13 11:35:08.766: D/i and Line::(1547): 0,NewSave,1,0,true,1,0,true,1,0,true,1,0,true,1,0,true,1,0,true,1,0,true,1,0,true,1,5,0,true??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????;

I wasn't sure if I needed to add "\n", "\r\n" or leave it without, as I am appending to the file. If I don't need either the new line then I need to null the end of the file from the last enrty with "\0" or something...

This was built on a fresh Geny Mototion AVD with SGS4 4.4.2 each execution, to ensure the file is freshly made.


Solution

  • The unwanted characters aren't being added to the file, the problem is in the way you read the data back in. You're not using the length returned by isr.read(inputBuffer).

    All you need to do is change

    isr.read(inputBuffer);
    data = new String(inputBuffer);
    

    to

    int length = isr.read(inputBuffer);
    data = new String(inputBuffer, 0, length);
    

    It doesn't break anything, but I'm also not sure why you convert your string array to a list and then back to an array here:

    List<String> lines = Arrays.asList(data.split("\n"));
    Object[] aLinesArray = lines.toArray();
    

    You could just do:

    String[] aLinesArray = data.split("\n");