【问题标题】:Mysterious IOException while writing a file写入文件时出现神秘的 IOException
【发布时间】:2012-02-26 00:24:47
【问题描述】:

这是我用来将文件.name 写入路径/sdcard/ 中名称以cimage 开头的某些文件夹的代码。目前我有 4 个这样的文件夹,其中 2 个是最近创建的。问题出在这两个上,并且会影响我以后手动添加的任何文件夹。

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)));
        }
    }

}

所以发生的情况是,当该方法尝试写入最后 2 个文件夹时,它会抛出一个 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

我找不到这种行为的解释。如果您想知道,所有其他应用程序都可以写入这些文件夹。这可能是什么原因造成的?

【问题讨论】:

  • @TomasVoracek 怎么做?
  • 使用 IOException.printStackTrace,或者只是在调试模式下检查可用的方法/属性。 stackoverflow.com/questions/8217500/…
  • @TomasVoracek 添加e.printStackTrace(); 不要给我任何额外的堆栈。
  • @TomasVoracek 这是文件未找到异常,谢谢,我会修复它。
  • 刚刚注意到一件事 - 您没有在 try 语句中关闭/处理 File、FileReader、BufferedReader 对象。它总是这样的错误的来源。

标签: java android


【解决方案1】:

使用 LogCat 将错误记录到控制台,请参阅 How to print stacktrace for an exception Android

还检查堆栈跟踪,它包含有关错误的最有用信息。

【讨论】:

    【解决方案2】:

    这并不神秘,我只是忘记为 .name 不存在的情况添加一个循环。添加此循环修复它。

    ........
    ........
    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];
    ........
    ........
    

    【讨论】:

      【解决方案3】:

      很大一部分问题在于:

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

      您将丢弃IOException 中捕获的所有信息,包括实际异常的名称及其消息。丢弃基本的异常信息是不好的做法……而且你已经被烧死了。

      最佳做法是使用 Log.e(tag, msg, throwable) 重载将异常包含在日志中。

      或者,如果这是“用户错误”,您需要诊断问题并将其报告给用户。为此,您可能需要捕获 IOException 的相关子类型(例如 FileNotFoundException)并相应地调整您的最终用户诊断和恢复。

      【讨论】:

        猜你喜欢
        • 2014-01-14
        • 2017-12-07
        • 2011-09-10
        • 1970-01-01
        • 1970-01-01
        • 2012-07-13
        • 1970-01-01
        • 1970-01-01
        • 2011-12-24
        相关资源
        最近更新 更多