Java 获取奇怪的filenotfoundexception

Java 获取奇怪的filenotfoundexception,java,android,android-file,Java,Android,Android File,谈到Android,我目前处于初级阶段&我目前正在为我目前面临的一个问题挠头 我正在创建一个Android应用程序,以检查内部存储中是否存在“cache.json”: 如果它不存在,那么首先创建它&将从httpapi获取的字符串写入该文件(在下面的代码中替换为固定字符串) 不管怎样,在完成写入后读取文件(如果需要)并执行适当的操作 这是代码片段: public class ShowClasses extends AppCompatActivity { @Override p

谈到Android,我目前处于初级阶段&我目前正在为我目前面临的一个问题挠头

我正在创建一个Android应用程序,以检查内部存储中是否存在“cache.json”:

  • 如果它不存在,那么首先创建它&将从httpapi获取的字符串写入该文件(在下面的代码中替换为固定字符串)
  • 不管怎样,在完成写入后读取文件(如果需要)并执行适当的操作
这是代码片段:

public class ShowClasses extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        filename = "cache.json";
        file = new File(getApplicationContext().getFilesDir(), filename);

        if (file.exists()) {
            System.out.println("EXISTS");
        } else {
            System.out.println("DOES NOT EXIST");
            writeFile();
        }

        readFile();
    }

    public void writeFile() {
        new JsonTask().execute(email);
    }

    public void readFile() {
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        int c;
        result = "";
        try {
            while( (c = fin.read()) != -1){
                result = result + Character.toString((char)c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            fin.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return;
    }

    private class JsonTask extends AsyncTask<String, Void, String> {

        protected void onPreExecute() {
            result = ""; // Clear result
            super.onPreExecute();
            pd.setMessage("Please wait");
            pd.setCancelable(false);
            pd.show();
        }

        protected String doInBackground(String... params) {
            return "THIS STRING IS GOING TO BE RETURNED " + params[0];
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);    

            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }

            FileOutputStream fileout = null;

            try {
                fileout = new FileOutputStream(file);
                fileout.write(result.getBytes());
                //display file saved message
                msg("File saved successfully!");

            } catch (Exception e) {
                e.printStackTrace();
            }

            try {
                fileout.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (pd.isShowing()){
                pd.dismiss();
            }

        }
    }
}
公共类ShowClasses扩展了AppCompative活动{
@凌驾
创建时受保护的void(Bundle savedInstanceState){
filename=“cache.json”;
file=新文件(getApplicationContext().getFilesDir(),文件名);
if(file.exists()){
System.out.println(“存在”);
}否则{
System.out.println(“不存在”);
writeFile();
}
readFile();
}
公共无效写入文件(){
新建JsonTask().execute(电子邮件);
}
公共void readFile(){
FileInputStream fin=null;
试一试{
fin=新文件输入流(文件);
}catch(filenotfounde异常){
e、 printStackTrace();
}
INTC;
结果=”;
试一试{
而((c=fin.read())!=-1){
结果=结果+字符.toString((char)c);
}
}捕获(IOE异常){
e、 printStackTrace();
}
试一试{
fin.close();
}捕获(IOE异常){
e、 printStackTrace();
}
返回;
}
私有类JsonTask扩展了异步任务{
受保护的void onPreExecute(){
result=”“;//清除结果
super.onPreExecute();
pd.setMessage(“请稍候”);
pd.可设置可取消(假);
pd.show();
}
受保护的字符串doInBackground(字符串…参数){
return“此字符串将被返回”+params[0];
}
@凌驾
受保护的void onPostExecute(字符串结果){
super.onPostExecute(结果);
试一试{
createNewFile();
}捕获(IOE异常){
e、 printStackTrace();
}
FileOutputStream fileout=null;
试一试{
fileout=新的FileOutputStream(文件);
write(result.getBytes());
//显示文件保存消息
msg(“文件保存成功!”);
}捕获(例外e){
e、 printStackTrace();
}
试一试{
fileout.close();
}捕获(IOE异常){
e、 printStackTrace();
}
if(pd.isShowing()){
pd.解散();
}
}
}
}
我试图删除代码中不必要的部分,使其长度更小

我面临的实际问题是当writeFile()和readFile()都被调用时。当我打开流时,我在readFile()中得到一个FileNotFoundException,即使该文件应该创建,因为writeFile()是在readFile()之前调用的

如果我在一次执行中写入文件,然后在另一次执行中调用readFile(),那么它就可以正常工作

这就是我面临的错误

System.err:java.io.FileNotFoundException:/data/user/0/host.timeline.timetablenotifier/files/cache.json(没有这样的文件或目录) System.err:at java.io.FileInputStream.open(本机方法)

任何帮助都将不胜感激


感谢您,AsyncTask在后台线程中运行,这样主线程中的其他代码就不会等待执行完成。更简单地说,您的
readFile()
方法是在
writeFile()
完成之前执行的,因此存在
FileNotFoundException
。如果您将
readFile()
方法放在
onPostExecute()
方法的末尾,将
Asynctask

Asynctask
放在后台线程中运行,那么主线程中的其他代码就不会等待执行完成。更简单地说,您的
readFile()
方法是在
writeFile()
完成之前执行的,因此存在
FileNotFoundException
。如果将
readFile()
方法放在
onPostExecute()
方法的末尾,则可以在
Asynctask中使用
writeFile()
方法。当该方法返回时,该文件没有发生任何事情。最多可以调用
JsonTask
onPreExecute()
。因此,当您调用
readFile()
时,该文件将不存在

除此之外:

  • 您在
    writeFile()
    中使用了一个
    AsyncTask
    ,但是您在
    onPostExecute()
    中执行磁盘I/O,并且在主应用程序线程上调用该方法

  • 您正在
    readFile()
    中的主应用程序线程上执行磁盘I/O

  • 捕捉异常,记录它们,然后继续执行代码,而大多数异常意味着后面的语句也将失败

  • 出于性能原因,一次读取一个
    int
    数据并不是接近20年的推荐方法

  • 由于
    AsyncTask
    ProgressDialog
    都不能解释配置更改,因此您将遇到多个与配置更改相关的问题,例如屏幕旋转

此外:

  • getApplicationContext().getFilesDir()
    可以在
    onCreate()中替换为
    getFilesDir()

  • 您不需要
    createNewFile()