为什么有时它会抛出FileNotFoundException

lan*_*nyf 17 android filenotfoundexception fileoutputstream

代码大部分时间都有效,但有时会引发异常.无法弄清楚是什么原因造成的.

什么是在...创建文件

/storage/emulated/0/Download/theFileName.jpg

并向其写入数据(来自sourceFile,确实存在),但新创建的文件得到"文件不存在"异常.

(它确实有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) {}
}
Run Code Online (Sandbox Code Playgroud)

aga*_*aga 8

我可以想到以下可能的原因:

  1. 无法创建新文件只是因为SD卡上没有可用空间.下次遇到此问题时,请尝试通过文件管理器或"设置" - >"存储"查看是否至少有一些可用空间.如果这是用户设备上发生的事情,我怀疑你可以做些什么.
  2. 由于某些操作系统故障或物理上未连接SD卡,因此无法使用SD卡,因此无法创建文件.再一次 - 除了显示一些Toast错误消息之外,你无能为力.
  3. 如何生成fileName文件路径的一部分?有时无法创建文件,因为文件名包含不受支持的(通过此特定设备)字符.例如我有Android 4.1.2的HTC Desire X,如果文件名包含冒号,则无法使用类似于您的代码创建文件.尝试另一种方法来生成文件名,看看它是否有所作为.
  4. Downloads在创建文件之前,您是否确定该目录存在?写下面的内容:

    if (!downloadDirectory.exists()) {
        downloadDirectory.mkdirs();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. WRITE_EXTERNAL_STORAGE权限在Android 6上被视为危险,因此用户可以随时撤消该权限.确保用户在写入文件之前未撤消此权限.
  6. 使用完毕后始终关闭I/O流.将该finally子句添加到try-catch块并关闭其中的两个inout流:

    finally {
        if (in != null) {
            try {
                in.close();
            } catch (Exception e) { }
        }
    
        if (out != null) {
            try {
                out.close();
            } catch (Exception e) { }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  7. 最后一个 - 最后我没有选择.:)我想如果你从多个线程写入同一个文件也会出现这个问题.如果是这种情况,请尝试同步对文件编写代码的访问.