Binoy Babu
Binoy Babu

Reputation: 17119

Mysterious IOException while writing a file

This is the code I'm using to write a file .name to some folders in path /sdcard/ that with name starts with cimage. Currently I have 4 such folders, 2 of them were created lately. The problem is with these two and affects any folder that I manually add later.

public static void WriteName(ArrayList<String> citem) {
    final String not_writable = "norw";
    for (int i = 0; i < citem.size(); i++) {
        try {
            File root = new File(Environment.getExternalStorageDirectory()
                    .getName() + "/" + citem.get(i));
            File namefile = new File(root, ".name");
            FileReader namereader = new FileReader(namefile);
            BufferedReader in = new BufferedReader(namereader);
            String[] str_array = new String[4];
            str_array[0] = in.readLine();
            str_array[1] = in.readLine();
            str_array[2] = in.readLine();
            str_array[3] = in.readLine();
            Log.d("NameWrite", "line 4: " + str_array[3]);
            if (str_array[3] == null || !str_array[3].equals(not_writable)) {
                FileWriter namewriter = new FileWriter(namefile);
                BufferedWriter out = new BufferedWriter(namewriter);
                out.write(i
                        + "\nCImage_"
                        + (i)
                        + "\nAutogenerated Stub\nnorw\n");
                out.close();
            } else {
                Log.d("NameManager.WriteName", "Skipping " + root
                        + ", norw set");
            }
        } catch (IOException e) {
            Log.e("NameManager.java : ", ("Error!! Not Writable!!"
                    + Environment.getExternalStorageDirectory().getName()
                    + "/" + citem.get(i)));
        }
    }

}

So what happens is that when the method tries to write the last 2 folders it throws an IOException.

02-26 05:42:39.663: D/NameManager.java(5316): Checking for whatever
02-26 05:42:39.671: D/NameManager.java(5316): SDcard mounted RW
02-26 05:42:40.694: D/java.lang.java.lang.String(5316): file (43) :cimages
02-26 05:42:40.694: D/java.lang.java.lang.String(5316): file (76) :cimages_1
02-26 05:42:40.694: D/java.lang.java.lang.String(5316): file (77) :cimageslkj
02-26 05:42:40.694: D/java.lang.java.lang.String(5316): file (81) :cimages_2
02-26 05:42:40.694: D/NameWrite(5316): line 4: norw
02-26 05:42:40.694: D/NameManager.WriteName(5316): Skipping sdcard/cimages, norw set
02-26 05:42:40.702: D/NameWrite(5316): line 4: norw
02-26 05:42:40.702: D/NameManager.WriteName(5316): Skipping sdcard/cimages_1, norw set
02-26 05:42:40.702: E/NameManager.java :(5316): Error!! Not Writable!!sdcard/cimageslkj
02-26 05:42:40.710: E/NameManager.java :(5316): Error!! Not Writable!!sdcard/cimages_2
02-26 05:42:40.725: D/java.lang.java.lang.String(5316): file (77) :cimageslkj

I can find no explanation for this behavior. All other apps can write to those folder in case you are wondering. What might be causing this?

Upvotes: 0

Views: 864

Answers (3)

Stephen C
Stephen C

Reputation: 718678

A large part of the problem is in this:

        } catch (IOException e) {
            Log.e("NameManager.java : ", ("Error!! Not Writable!!"
                + Environment.getExternalStorageDirectory().getName()
                + "/" + citem.get(i)));
        }

You are discarding all of the information in the IOException that you've caught, including the name of the actual exception and its message. It is Bad Practice to throw away basic exception information ... and you've been burned.

Best practice is to include the exception in the log by using the Log.e(tag, msg, throwable) overload.

Alternatively, if this was a "user mistake", you'd need to diagnose the problem and report it to the user. To do this, you'd probably need to catch relevant subtypes of IOException (e.g. FileNotFoundException) and tailor your end-user diagnostics and recovery accordingly.

Upvotes: 0

Binoy Babu
Binoy Babu

Reputation: 17119

It's nothing mysterious, I just forgot to add a loop for cases in which .name don't exist. Adding this loop fixed it.

........
........
try {
                File root = new File(Environment.getExternalStorageDirectory()
                        .getName() + "/" + fsitem.get(i));
                File namefile = new File(root, ".name");
                if (!namefile.exists()){
                    namefile.createNewFile();
                }
                FileReader namereader = new FileReader(namefile);
                BufferedReader in = new BufferedReader(namereader);
                String[] str_array = new String[4];
........
........

Upvotes: 0

Tomas Voracek
Tomas Voracek

Reputation: 5914

Use LogCat for error logging to console, see How to print stacktrace for an exception Android.

Also inspect stack trace, it has most useful info about error.

Upvotes: 1

Related Questions