Android API 22中的FileOutputStream返回FileNotFoundException

3

我正在尝试从服务器下载一个pdf文件。我写了一些代码。在api级别为21和>=23时,它可以正常工作,但在api 22上却无法工作。这是问题所在:

OutputStream output = new FileOutputStream(fileName);
byte data[] = new byte[1024];

while ((count = input.read(data)) != -1) {
   output.write(data, 0, count);
}

但是当它尝试执行时,
 OutputStream output = new FileOutputStream(fileName); 

它展示了

java.io.FileNotFoundException: /storage/emulated/0/data    /data/com.example.test/files/training/training.pdf: open failed: ENOENT (No such file or directory)

这在API级别为21和23时运行良好。出了什么问题?我该如何解决?


从Android开发者控制台来看,如果“该文件存在但是是一个目录而不是常规文件,不存在但无法创建或由于其他原因无法打开”,则会出现FileNotFoundException异常。这意味着,如果文件不存在,它将创建新文件。 - coder
请检查此链接:https://dev59.com/9WYq5IYBdhLWcg3wkRYo 或者像@JonasKöritz所说,您在FileOutputStream()构造函数中传递了什么类型的文件? - Farmer
@Shailesh,我的理解是对的吗:如果没有文件,它会创建一个新文件? - coder
是的,因为如果文件不存在并尝试读取它,那么这怎么可能呢?你需要先检查文件是否存在,如果文件不存在,则创建文件,然后再尝试读取。 - Farmer
在调用FileOutputStream()之前,我会调用以下方法:public void createDirectory() { File directory = new File(getFilesDir() + "/training"); if (!directory.exists()) { directory.mkdir(); } } - coder
显示剩余7条评论
1个回答

3
在调用FileOutputStream()之前,我会先调用public void createDirectory()方法: { File directory = new File(getFilesDir() + "/training"); if (!directory.exists()) { directory.mkdir(); } }
这并不是你尝试写文件的地方:
String root = Environment.getExternalStorageDirectory().toString(); String path = path = "/training/training.pdf"; String fileName = fileName=root+"/"+getFilesDir()+path;
正如你所看到的,它们并不匹配。
如果您希望将文件存储在外部存储上,最好的解决方案是摒弃所有这些,并使用调用Context(类似于getFilesDir())的getExternalFilesDir()。这将为您提供:
  • 一个唯一的目录
  • 在外部存储上
  • 当您的应用被卸载时,这些文件将被删除
  • 在Android 4.4+上不需要权限

外部存储的次佳解决方案是摒弃所有这些,并使用Environment.getExternalStoragePublicDirectory()作为基础,以根据其类型(例如照片、视频、音乐)将文件放置在标准位置中。这些文件将在卸载后仍然存在,并且此位置将需要WRITE_EXTERNAL_STORAGE权限。此外,您将需要在此根目录下自己创建一个唯一的子目录,尽管通常是通过用户友好的显示名称(例如OpenCamera)而不是包名来完成此操作。

您在createDirectory()中创建的目录是完全正常的,但它是内部存储,因此用户无法访问它。如果您想使用它,请使用与createDirectory()中使用的相同算法来创建FileOutputStreamFile。请保留HTML标签。

非常感谢。我之前从根目录读取文件,其实没有必要。现在我使用了getFilesDir()方法,问题解决了! - coder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接