Android异常--java.io.FileNotFoundException下载文件时异常

问题分析

在下载文件时,报的异常如下所示:FileNotFoundException

10-24 11:16:44.446  3936  7905 W System.err: java.io.FileNotFoundException: /sdcard/MDS/Jellyfish.jpg: open failed: ENOENT (No such file or directory)
10-24 11:16:44.446  3936  7905 W System.err:    at libcore.io.IoBridge.open(IoBridge.java:456)
10-24 11:16:44.446  3936  7905 W System.err:    at java.io.RandomAccessFile.(RandomAccessFile.java:117)
10-24 11:16:44.446  3936  7905 W System.err:    at java.io.RandomAccessFile.(RandomAccessFile.java:149)
10-24 11:16:44.446  3936  7905 W System.err:    at com.***.httpclient.download.DownloadTask.run(DownloadTask.java:83)
10-24 11:16:44.446  3936  7905 W System.err:    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
10-24 11:16:44.446  3936  7905 W System.err:    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-24 11:16:44.446  3936  7905 W System.err:    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
10-24 11:16:44.446  3936  7905 W System.err:    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
10-24 11:16:44.446  3936  7905 W System.err:    at java.lang.Thread.run(Thread.java:818)
10-24 11:16:44.446  3936  7905 W System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
10-24 11:16:44.456  3936  7905 W System.err:    at libcore.io.Posix.open(Native Method)
10-24 11:16:44.456  3936  7905 W System.err:    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
10-24 11:16:44.456  3936  7905 W System.err:    at libcore.io.IoBridge.open(IoBridge.java:442)
10-24 11:16:44.456  3936  7905 W System.err:    ... 8 more

查看对应行数的代码如下:

file = new RandomAccessFile(mSaveDirPath + mFileName, "rwd");

查看RandomAccessFile的文档说明,

RandomAccessFile
public RandomAccessFile(String name,
                String mode)
                 throws FileNotFoundException
Creates a random access file stream to read from, and optionally to write to, a file with the specified name. A new FileDescriptor object is created to represent the connection to the file.
The mode argument specifies the access mode with which the file is to be opened. The permitted values and their meanings are as specified for the RandomAccessFile(File,String) constructor.

If there is a security manager, its checkRead method is called with the name argument as its argument to see if read access to the file is allowed. If the mode allows writing, the security manager's checkWrite method is also called with the name argument as its argument to see if write access to the file is allowed.

Parameters:
name - the system-dependent filename
mode - the access mode
Throws:
IllegalArgumentException - if the mode argument is not equal to one of "r", "rw", "rws", or "rwd"
FileNotFoundException - if the mode is "r" but the given string does not denote an existing regular file, or if the mode begins with "rw" but the given string does not denote an existing, writable regular file and a new regular file of that name cannot be created, or if some other error occurs while opening or creating the file
SecurityException - if a security manager exists and its checkRead method denies read access to the file or the mode is "rw" and the security manager's checkWrite method denies write access to the file
See Also:
SecurityException, SecurityManager.checkRead(java.lang.String), SecurityManager.checkWrite(java.lang.String)

触发FileNotFoundException异常的可能情况如下:
“如果该模式为 “r”,但给定的字符串表示一个现有的常规文件,或者该模式以 “rw” 开头,但给定的字符串不表示一个现有的可写常规文件,而且无法创建具有该名称的新常规文件,或者在打开或创建该文件时发生一些其他错误”(翻译的一般,能懂就好)。


总结起来,就是文件存在,但不能正常访问;或文件不存在,又不能正常创建;那么就要报FileNotFoundException 的异常。


问题原因

在创建RandomAccessFile(mSaveDirPath + mFileName, “rwd”);时,采用的是文件路径+文件名称的方式。
根据android终端机型及各个生产厂商的不同,直接创建“文件路径”+“文件名称”的方式,有的可能支持,有的可能不支持。当不支持此方式创建文件时,就好出现FileNotFoundException 异常。

解决方式

先创建路径,再创建文件
具体有如下两种方式:
1. 在应用Application创建时,判断文件路径是否已经创建,若没有创建,则新建该文件夹。
2. 在下载之前判断,mSaveDirPath 路径是否存在,不存在则创建。注意如果是在线程中创建,则要考虑多线程等相关问题。

参考代码:

Application::onCreate~

File filePath = new File(Define.SAVE_PATH);
if(!filePath.exists()){
filePath.mkdirs()
}

你可能感兴趣的:(Android异常)