为什么有时它抛出FileNotFoundException异常

问题描述 投票:17回答:6

该代码适用于大多数的时间,但有些时候它会抛出异常。想不出什么可能导致它。

什么是确实是在创建一个文件

/storage/emulated/0/download/the filename.jpg

和写入(从它的资源文件确实存在)的数据,却得到了“文件不存在”异常为新创建的文件。

(它确实有uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE", and uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE”清单中)。

File sourceFile = new File(theSourceFileFullPath);
if (sourceFile.exists()) {
    File downloadDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    String downloadPath = downloadDirectory.getPath();
    String newFilePath = (downloadPath + "/" + fileName);
    File newFile = new File(newFilePath);
    try {
        FileInputStream in = new FileInputStream(sourceFile);

        // ava.io.FileNotFoundException: 
        //     /storage/emulated/0/Download/theFileName.jpg: open failed: ENOENT (No such file or directory) 
        // exception at this line       
        FileOutputStream out = new FileOutputStream(newFile);
        //......
     } catch (Exception e) {}
}
android filenotfoundexception fileoutputstream
6个回答
7
投票

我能想到的这种行为如下可能的原因:

  1. 新的文件不能简单地创作,因为有SD卡上没有可用空间。您遇到这个问题,在下一次尝试看看,如果你通过文件管理器或设置有至少一些可用空间 - >存储。我怀疑你可以做一些事情,如果这是你的用户的设备上会发生什么。
  2. SD卡无法使用,由于一些操作系统故障或它的身体没有连接,因此该文件无法创建。再一次 - 没有什么可以做这件事,不是显示一些Toast与错误信息等。
  3. 你如何生成文件的路径fileName一部分? Sometimes文件不能被创建,因为文件名中包含不支持的(由这个特定的装置)的字符。例如。我有与Android 4.1.2的HTC Desire X,如果文件名中包含冒号不能与你类似的代码创建文件。尝试另一种方式来生成的文件名,看看它是否有差别。
  4. 你确定了Downloads目录中创建它里面的文件之前存在?写类似如下: if (!downloadDirectory.exists()) { downloadDirectory.mkdirs(); }
  5. 所述WRITE_EXTERNAL_STORAGE许可被认为dangerous对Android 6,因此可通过在任何时间用户撤销。 Make sure用户写入文件前未撤销此权限。
  6. Always close the I/O stream当你完成了它的工作。在finally条款添加到您的try-catch块,并关闭它都inout流: finally { if (in != null) { try { in.close(); } catch (Exception e) { } } if (out != null) { try { out.close(); } catch (Exception e) { } } }
  7. 最后一个 - 最后我出的选项。 :)我想,如果你写从多个线程在同一文件也可能出现这个问题。如果是这样的话,尝试同步访问您的文件编写代码。

2
投票

根据Java文档 - Class FileNotFoundException

public class FileNotFoundException extends IOException

信号,一个试图打开指定路径名表示的文件失败。

此异常将被FileInputStreamFileOutputStreamRandomAccessFile构造函数抛出当指定pathname文件不存在。它也将受到这些构造函数抛出如果文件确实存在,但由于某种原因无法访问,例如,当试图打开一个只读文件进行写操作。

要恢复,有三种情况,其中一个FileNotFoundException可能抛出。

  1. 命名的文件不存在。
  2. 命名文件实际上是一个目录。
  3. 指定的文件不能读取由于某些原因被打开。

得到了新创建的文件“文件不存在”异常。

在你的代码,我没有看到两件事情

  1. 成功写入后删除文件。我不是开玩笑的。如果我有这样的和错误的一类,我会做一种考验,这将与源文件复制内容后删除downlaodDirectory完成。在这种情况下,它会通过方法或者你会得到另一种,但更具体的错误 - 就像我的话:无法删除文件。在使用它
  2. 数据写入后关闭文件。我不也看到了方法来关闭文件。在你的代码,似乎是您的文件仍然是开放的,所以你再运行一个应用程序,你会得到这个不可预知的错误你。

要解决这个问题,只要关闭这两个文件使用file.close()方法处理数据之后。

希望它能帮助


1
投票
  1. 这个问题可能要创建文件的方式发生因: String downloadPath = downloadDirectory.getPath(); String newFilePath = (downloadPath + "/" + fileName); File newFile = new File(newFilePath); 危险的代码是在这里: String newFilePath = (downloadPath + "/" + fileName); 相反,尝试用下面的办法: File newFile = new File(downloadDirectory, fileName);
  2. SD卡的可用性 - 检查下列文件http://developer.android.com/training/basics/data-storage/files.html#WriteExternalStorage。这可能是媒体不安装(例如在它发生的一些旧设备时,用户通过USB连接电脑设备)所以,尽量以检查是否安装介质: /* Checks if external storage is available for read and write */ public boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false; } 并通知用户如果不。

0
投票

你没贴全异常堆栈痕迹,但我发现确切的问题这么解决了。

java.io.FileNotFoundException: /storage/emulated/0/bimagechooser/1429031333305.jpg: open failed: ENOENT (No such file or directory)

使用这个库image-chooser-library.&需要重新因子代码。

盖伊coomar2841。一定会帮助你的。他花时间解决问题。所以节省您的时间。

接过com.kbeanie.imagechooser的代码,将其投进你的APP,去掉了gradle这个声明库和应用程序应该工作。

请查看GitHub Issue

我希望它会为你工作。 :)


0
投票

我希望在文件中是完美的,我只是精矿您的疑难问题想在两个可能获得没有发现异常文件的代码写入数据。

  1. 当你提供这种性格的当时的文件给出文件名不正确生成,这就是为什么这个错误是发生所以请确保您的文件名是正确的一段时间,文件名是不支持某些特殊字符。
  2. 第二是你的文件extension.here你没有指定你有哪些类型的文件。

在这里我有一些代码片段,我希望这会帮助你解决问题。

   File file=new File(Environment.getExternalStorageDirectory()+"/"+ConstansClass.FOLDERNAME);
    if(!file.exists())
    {
        file.mkdir();
    }


    String file=filename.replaceAll("[^a-zA-Z0-9.-]", " ");
    yourDir = new File(file, file+".mp3");
    if(yourDir.exists())
    {
        return yourDir;
    }

编辑

我对不起我lannf不知道在你的代码究竟会发生,但我有一个代码片断这是刚刚从soundcloude和Store下载的MP3文件在我的本地storage.i认为这是为你的requirement.so完全一样,我有我的后下面的代码。

 @Override
protected File doInBackground(Void... params) {


    //File sdCardRoot = Environment.getExternalStorageDirectory()+"/Music";

    File file=new File(Environment.getExternalStorageDirectory()+"/"+ConstansClass.FOLDERNAME);
    if(!file.exists())
    {
        file.mkdir();
    }


    String filename=soundCloudeResponse.getTitle();//.replaceAll("[^a-zA-Z0-9.-]", " ");
    yourDir = new File(file, filename+".mp3");
    if(yourDir.exists())
    {
        return yourDir;
    }
    String url=soundCloudeResponse.getStream_url()+"?"+ConstansClass.SOUNDCLOUDE_CLIENT_ID;

    URL u = null;
    try {
        DebugLog.e("Request Url"+ url);
        u = new URL(url);
        URLConnection conn = u.openConnection();
        int contentLength = conn.getContentLength();

        DataInputStream stream = new DataInputStream(u.openStream());

        byte[] buffer = new byte[contentLength];
        stream.readFully(buffer);
        stream.close();

        DataOutputStream fos = new DataOutputStream(new FileOutputStream(yourDir));
        fos.write(buffer);
        fos.flush();
        fos.close();
        DebugLog.d("Download Complete in On Background");


    } catch (MalformedURLException e) {
        sucess=false;
        e.printStackTrace();

    } catch (IOException e) {
        sucess=false;
        e.printStackTrace();

    }
    catch (Exception e)
    {
        sucess=false;
        e.printStackTrace();
        DebugLog.e("Error ::"+e.getMessage());
    }


    return yourDir;
}

我觉得你是很聪明的开发人员,所以您可以根据您的要求修改这个代码。

好运


0
投票

有可能是一个更可能:

如果你的代码的一部分被写入文件,另一种是读书,那么这是好事,认为作家写完的文件之前,读者阅读。

您可以穿越把你的代码在调试模式下检查这种情况。如果它工作正常那里,给你FileNotFoundException异常,那么可以肯定这可能是此异常的潜在原因。

现在,如何解决:

您可以使用类似于下面的代码块重试机制的东西

if(!file..exists()){
Thread.sleep(200);}

在你的代码,并根据您的需要改变睡眠值。

希望帮助。!

© www.soinside.com 2019 - 2024. All rights reserved.