代码大部分时间都有效,但有时会引发异常。无法弄清楚可能导致它的原因。
在
创建文件是做什么的/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) {}
}
答案 0 :(得分:7)
我可以想到以下可能的原因:
Toast
显示错误消息之外,您无能为力。fileName
部分? Sometimes无法创建文件,因为文件名包含不受支持的(通过此特定设备)字符。例如。我有Android 4.1.2的HTC Desire X,如果文件名包含冒号,则无法使用类似于你的代码创建文件。尝试另一种方法来生成文件名,看看它是否有所作为。在创建文件之前,您确定Downloads
目录是否存在?写下如下内容:
if (!downloadDirectory.exists()) {
downloadDirectory.mkdirs();
}
WRITE_EXTERNAL_STORAGE
权限被视为dangerous,因此用户可以随时撤消该权限。 Make sure用户在写入文件之前未撤消此权限。 Always close the I/O stream。将finally
子句添加到try-catch块并关闭其中的in
和out
个流:
finally {
if (in != null) {
try {
in.close();
} catch (Exception e) { }
}
if (out != null) {
try {
out.close();
} catch (Exception e) { }
}
}
答案 1 :(得分:2)
根据Java文档 - Class FileNotFoundException:
public class FileNotFoundException extends IOException
表示尝试打开由指定路径名表示的文件失败。
FileInputStream
将抛出此异常, 当文件包含时,FileOutputStream
和RandomAccessFile
构造函数 指定的pathname
不存在。它也会被这些抛出 构造函数如果文件存在但由于某种原因是 无法访问,例如尝试打开只读时 写作文件。
要恢复,有三种情况可能会抛出FileNotFoundException
。
得到"文件不存在"新创建的文件的例外。
在您的代码中,我没有看到两件事
downlaodDirectory
完成。在这种情况下,它会传递方法,或者你会得到另一个,但更具体的错误 - 就像在我的话:无法删除文件。在使用它 要解决此问题,请在使用file.close()
方法处理数据后关闭这两个文件。
希望有所帮助
答案 2 :(得分:1)
由于您创建文件的方式,可能会发生此问题:
String downloadPath = downloadDirectory.getPath();
String newFilePath = (downloadPath + "/" + fileName);
File newFile = new File(newFilePath);
危险代码在这里:
String newFilePath = (downloadPath + "/" + fileName);
相反,请尝试使用以下方法:
File newFile = new File(downloadDirectory, fileName);
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;
}
如果没有通知用户。
答案 3 :(得分:0)
我希望你的代码在文件中写入数据是完美的我只是专注于你的问题。我认为有两种可能性让文件找不到例外。
这里我有一些代码片段我希望这能帮助你解决问题。
<强>解决方案强>
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下载mp3文件并存储在我的本地storage.i认为它与你的需求完全相同。所以我发布了我的代码。
@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;
}
我认为您是智能开发人员,因此您可以根据自己的要求修改此代码。
最好的运气
答案 4 :(得分:0)
你没有发布完整的异常堆栈跟踪,但我发现确切的问题已经解决了。
java.io.FileNotFoundException: /storage/emulated/0/bimagechooser/1429031333305.jpg: open failed: ENOENT (No such file or directory)
使用此库image-chooser-library.&amp;需要重新计算代码。
The Guy coomar2841。一定会帮到你。因为他花了几个小时来解决问题。所以节省你的时间。
获取com.kbeanie.imagechooser的来源并将其放入您的APP,删除了库的gradle声明,APP应该可以正常工作。
请查看 GitHub Issue
我希望它对你有用。 :)
答案 5 :(得分:0)
可能还有另外一种可能性:
如果代码的一部分正在写入文件,而另一部分正在读取文件,那么最好在写入者完成写入文件之前考虑读者正在读取文件。
您可以通过将代码置于调试模式来交叉检查这种情况。如果在该处工作正常,并给您FileNotFoundException,那么肯定是造成此异常的潜在原因。
现在,如何解决:
您可以使用类似于以下代码块的重试机制
if(!file..exists()){
Thread.sleep(200);}
在您的代码中,并根据需要更改睡眠值。
希望有帮助!!