TAGS :Viewed: 14 - Published at: a few seconds ago

[ How to read/write a string encoded with android.util.Base64 ]

I would like to store some strings in a simple .txt file and then read them, but when I want to encode them using Base64 it doesn't work anymore: it writes well but the reading doesn't work. ^^

The write method:

private void write() throws IOException {
    String fileName = "/mnt/sdcard/test.txt";
    File myFile = new File(fileName);

    BufferedWriter bW = new BufferedWriter(new FileWriter(myFile, true));

    // Write the string to the file
    String test = "http://google.fr";
    test = Base64.encodeToString(test.getBytes(), Base64.DEFAULT);

    bW.write("here it comes"); 


    // save and close

The read method :

private void read() throws IOException {
    String fileName = "/mnt/sdcard/test.txt";
    File myFile = new File(fileName);
    FileInputStream fIn = new FileInputStream(myFile);

    BufferedReader inBuff = new BufferedReader(new InputStreamReader(fIn));
    String line = inBuff.readLine();
    int i = 0;
    ArrayList<List<String>> matrice_full = new ArrayList<List<String>>();
    while (line != null) {
        matrice_full.add(new ArrayList<String>());
        String[] tokens = line.split(";");

        String decode = tokens[1];
        decode = new String(Base64.decode(decode, Base64.DEFAULT));

        line = inBuff.readLine();

Any ideas why?

Answer 1

You have a couple of errors in your code.

First a couple of notes on your code:

  1. When posting here, attaching a SSCCE helps others to debug your code. This is not a SSCEE because it doesn't compile. It lacks several defined variables, so one must guess what you really mean. Also you have pasted close-comment token in your code: */ but there is no one start-comment token.
  2. Catching and just suppressing exceptions (like in catch-block in read method) is really bad idea unless you really know what you're doing. What it does most of the time is hide the potential problems from you. At least write the stacktrace of an exception is a catch block.
  3. Why don't you just debug it, check what exactly outputs to the destination file? You should learn how to do that because that will speed up your development process, especially for larger projects with hard-to-catch problems.

Back to the solution:

  1. Run the program. It throws an exception:

    02-01 17:18:58.171: E/AndroidRuntime(24417): Caused by: java.lang.ArrayIndexOutOfBoundsException

    caused by line here:


    inspecting the variable tokens reveals that it has 2 elements, not 3.

  2. So lets open the file generated by the write method. Doing that shows this output:

    here it comes;aHR0cDovL2dvb2dsZS5mcg==
    here it comes;aHR0cDovL2dvb2dsZS5mcg==
    here it comes;aHR0cDovL2dvb2dsZS5mcg==

    Note line breaking here. This is because the Base64.encodeToString() appends additional newline at the end of the encoded string. To generate a one single line, without extra newlines, add Base64.NO_WRAP as the second parameter like this:

    test = Base64.encodeToString(test.getBytes(), Base64.NO_WRAP);

    Note here, you must delete file that was created earlier as it has improper line breaking.

  3. Run the code again. It now creates a file with the proper contents:

    here it comes;aHR0cDovL2dvb2dsZS5mcg==;done
    here it comes;aHR0cDovL2dvb2dsZS5mcg==;done
  4. Printing the output of matrice_full now gives:

        [here it comes, aHR0cDovL2dvb2dsZS5mcg==, done],
        [here it comes, aHR0cDovL2dvb2dsZS5mcg==, done]

    Note that you're not doing anything with the value in decode variable in your code, hence the second element is the Base64 representation of that value which is read from the file.