1

我不明白为什么我们不进入第二个 if。我首先检查文件是否存在(不,逻辑),然后创建它,然后再次检查,但它仍然返回 false。我试了一个小时才找到问题,我确信这是一个愚蠢的错误。对不起我糟糕的英语

这是代码:

package com.example.testcreatefileonclick;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Main extends Activity implements android.view.View.OnClickListener{

    Button button;
    Button addTeam;
    Boolean append = true;

    String name = "nomFichier.txt";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        button = (Button)findViewById(R.id.button1);
        button.setOnClickListener((OnClickListener) this);
        addTeam = (Button)findViewById(R.id.button2);
        addTeam.setOnClickListener((OnClickListener) this);

    }

    @Override
    public void onClick(View v) {
        try {
            File fichier = new File(name);


            if (!fichier.exists()) {
                System.out.println("File doesn't exists");
            }


            FileOutputStream fOut = openFileOutput(name, MODE_WORLD_READABLE);
            OutputStreamWriter osw = new OutputStreamWriter(fOut); 
            osw.write("text");
            osw.flush();
            osw.close();

            //Why don't we go in this if ?
            if (fichier.exists()) {
                System.out.println("File exists");
            }


        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}

编辑:工作代码

package com.example.testcreatefileonclick;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Main extends Activity implements android.view.View.OnClickListener{

    Button button;
    Button addTeam;
    Boolean append = true;
    String name = "nomFichier.txt";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        button = (Button)findViewById(R.id.button1);
        button.setOnClickListener((OnClickListener) this);
        addTeam = (Button)findViewById(R.id.button2);
        addTeam.setOnClickListener((OnClickListener) this);

    }

    @Override
    public void onClick(View v) {
        try {
            String filePath = (this.getFilesDir().getPath().toString());
            File fichier = new File(filePath + name);

            if (!fichier.exists()) {
                System.out.println("File doesn't exists");
            }

            fichier.createNewFile();
            FileWriter file = new FileWriter(filePath + name);
            file.write("text");
            file.flush();
            file.close();

            if (fichier.exists()) {
                System.out.println("File exists");
            }


        } catch (IOException e) {
            System.out.println("Exception");
            e.printStackTrace();
        }
    }
}
4

3 回答 3

1

尝试替换这个:

FileOutputStream fOut = openFileOutput(name, MODE_WORLD_READABLE);
        OutputStreamWriter osw = new OutputStreamWriter(fOut); 
        osw.write("text");
        osw.flush();
        osw.close();

这样 :

fichier.createNewFile();
FileWriter file = new FileWriter(name);
file.write("text");
file.flush();
file.close();
于 2013-04-18T12:20:41.523 回答
1
// Why don't we go in this if ?

最可能的原因(IMO)是openFileOutput(name, MODE_WORLD_READABLE)引发异常。

如果发生这种情况,您将不会因为这段骇人听闻的代码而知道它。

    } catch (Exception e) {
        // TODO: handle exception
    }

为什么骇人听闻?

  1. 您正在捕获Exception而不是您希望抛出的特定异常(例如IOException)。
  2. 您正在“挤压”异常。你接住它,然后默默地扔掉它。

这些事情中的每一个都是不好的做法。一起做是......好吧......你应该为此浪费一个小时!


如果我对压扁异常的诊断不正确,那么还有另一种可能性。文档openFileOutput说:

“打开与此上下文的应用程序包关联的私有文件进行写入。” .

目前尚不完全清楚该文件将在何处打开/创建,但有可能它位于与File.exists正在查找的位置不同的“位置”。您会注意到它openFileOutput不会将File对象作为其输出。


最后,还有一个更微妙的问题,在这种情况下不会伤害你,但其他情况下会伤害你。你写了 ...

        if (!fichier.exists()) {
            System.out.println("File doesn't exists");
        }
        FileOutputStream fOut = openFileOutput(name, MODE_WORLD_READABLE);

问题在于存在竞争条件。在调用exists和调用之间openFileOutput,有一个小的时间窗口,其他应用程序可以在其中跳入并创建文件。因此,当您再调用时openFileOutput,它可能会发现该文件已经创建。

显然,在这种情况下,它没有任何区别。但在其他情况下可能会。教训是调用File.exists(),File.canWrite等等来“保护”以下创建/打开文件的尝试是不可靠的。

于 2013-04-18T12:17:30.017 回答
0

如果不是下面的异常问题,它可能正在缓存您第一次调用 exists 方法的结果(不太可能)。您可以在调用后尝试创建一个新的文件对象来测试它。

如果我愿意,我将使用 createNewFile 方法,该方法将返回一个布尔值供您在逻辑中使用。如果存在,这将比必须询问 IO 两次要好。

public boolean createNewFile() throws IOException
于 2013-04-18T12:18:51.690 回答