【问题标题】:DataOutputStream nullpointer exceptionDataOutputStream 空指针异常
【发布时间】:2014-02-24 18:59:16
【问题描述】:

我在 Android 中的 DataOutputStream 上获得了 NullPointerException

我首先使用DataOutputStream 编写了一些代码来用Java 写出文件。一切都很完美。我将代码导入到一个 Android 项目中,但出现了一些奇怪的行为。

我更改为特定于 android 的唯一代码是获取目录的方式。

所以到底发生了什么:我正在创建DataOutputStream,然后我正在关闭它。这就是现在的全部。我认为测试流是否正确打开是一个很好的第一步是关闭它。

DataOutputStream 是一个类实例变量。

当我以相同的方法调用它时,它会很好地关闭。当我从不同的方法调用它时,它会得到NullPointerException。但是在 Java 中执行这些相同的操作并不会导致问题,尽管它们在 Android 中会发生。

public class WavFileOutStream {

    private DataOutputStream stream;

    public WavFileOutStream(String fileName)
    {

        // Get the directory for the user's public pictures directory. 
        File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_RINGTONES), fileName);
        if (!file.mkdirs()) {
            Log.e("trace", "Directory not created");
        }

        try {
            stream = new DataOutputStream(new FileOutputStream(file));

            if(stream==null)
            {
                Log.i("trace","Null Stream!");
            }

            //<--PROBLEM LINE 1-->
            //If I call close from this line I get NO nullPointer
            //stream.close();


        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

        //<--PROBLEM LINE 1-->
        //If I call close from this line I get a nullPointer
        //I comment out other close() first
        close();

    }

    public void close()
    {
        try {
            stream.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

错误:

02-24 12:49:39.229: E/AndroidRuntime(11539): FATAL EXCEPTION: main
02-24 12:49:39.229: E/AndroidRuntime(11539): Process: com.example.ringtonegenerator, PID: 11539
02-24 12:49:39.229: E/AndroidRuntime(11539): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ringtonegenerator/com.example.ringtonegenerator.MainActivity}: java.lang.NullPointerException
02-24 12:49:39.229: E/AndroidRuntime(11539):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at android.app.ActivityThread.access$800(ActivityThread.java:135)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at android.os.Handler.dispatchMessage(Handler.java:102)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at android.os.Looper.loop(Looper.java:136)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at android.app.ActivityThread.main(ActivityThread.java:5017)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at java.lang.reflect.Method.invokeNative(Native Method)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at java.lang.reflect.Method.invoke(Method.java:515)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at dalvik.system.NativeStart.main(Native Method)
02-24 12:49:39.229: E/AndroidRuntime(11539): Caused by: java.lang.NullPointerException
02-24 12:49:39.229: E/AndroidRuntime(11539):    at com.example.ringtonegenerator.WavFileOutStream.close(WavFileOutStream.java:178)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at com.example.ringtonegenerator.WavFileOutStream.<init>(WavFileOutStream.java:43)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at com.example.ringtonegenerator.WavFileWriter.writeWave(WavFileWriter.java:10)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at com.example.ringtonegenerator.MainActivity.onCreate(MainActivity.java:23)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at android.app.Activity.performCreate(Activity.java:5231)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
02-24 12:49:39.229: E/AndroidRuntime(11539):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
02-24 12:49:39.229: E/AndroidRuntime(11539):    ... 11 more

【问题讨论】:

  • 你能显示你的 logcat 跟踪吗?

标签: java android file-io


【解决方案1】:

如果在创建流时抛出异常,流仍将为 null,您仍将调用 close。那里没有对 null 的检查,所以它会抛出 NPE。

public void close()
{
    if(stream != null){
        try {
            stream.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

【讨论】:

  • 我不明白。在这两种情况下都不会检查 null。
  • 没错。但是它有可能沿着异常路径为空;因此,它会在这种情况下抛出异常。您需要关闭它:
【解决方案2】:

catch 块之后的代码应该在 try 块内。这就是你获得 NPE 的原因。

根本问题是当你应该调用file.getParentFile().mkdirs()时你调用了file.mkdirs(),所以你将目标文件创建为一个目录,所以你不能创建目标文件,所以你得到一个 IOException 而不是创建 FileOutputStream,所以 DataOutputStream 引用仍然为空,所以当 catch 块之后的代码(应该在 try 块中)执行时,你会得到一个 NPE。

注意 'new' 的结果不能为空,所以事后直接测试是徒劳的。

【讨论】:

  • 为什么catch块后面的代码要在里面?它调用了另一种方法,其中有一个 try catch,它在 java 中运行良好,这不是问题。我将尝试使用 file.getParentFile().mkdirs()。我只是按照 android 参考文档中指定的确切代码来执行此操作。
  • 因为那样你不能得到 NPE。正如我在回答中所说的那样。
  • 我改成 file.getParentFile().mkdirs() 还是得到 NPE 并且没有创建目录。
  • 那么当你把应该在try块中的catch块之后的代码移到try块中时发生了什么?
  • 无空指针。最后,虽然我想检查空指针,所以我可以判断文件是否正确打开,并且似乎没有正确打开。我直接从 android 文档中遵循了代码,我添加了你的建议并且文件没有被打开。我添加了适当的权限。
猜你喜欢
  • 2015-07-12
相关资源
最近更新 更多