如何知道写入流是否会导致java.io.IOException:write failed:EBADF(Bad file number)

时间:2015-08-19 08:00:25

标签: java android io outputstream

我知道java.io.IOException: write failed: EBADF (Bad file number)例外的帖子中有很多帖子,但是其中没有帖子似乎回答了我的特定问题:

假设我的活动是通过Intent.ACTION_VIEW调用的,我通过Uri获得Uri uri = intent.getData()content://Uri开头,我从中读取了一些数据(例如pdf文件) 。现在我想知道是否也可以写ParcelFileDescriptor来决定是向用户显示“保存”按钮,还是只显示“另存为”按钮。

进一步假设我可以先成功打开FileOutputStream,最后成功打开ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "w"); FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor()); ,如

fileOutputStream != null

这样Uri

根据fileOutputStream现在可能发生的情况是,如果我尝试写入Exception=java.io.IOException: write failed: EBADF (Bad file number) ,我会得到例外:

Uri

我想事先知道这是否会在没有实际触摸/更改文件的情况下发生。有人会认为应该可以在尝试之前找出是否可以写给定的FileOutputStream

我怎样才能做到这一点?

补充意见:

我认为上述情况发生在我没有权限写入该特定文件/ uri时,但是为什么Android会让我首先打开uri

为了测试,我在ICS设备上使用Kaiten邮件收到的电子邮件中使用附件。如果我在Kaiten邮件中点击“保存”后我的应用程序打开content://media/external/file/[0-9]*匹配uri并且一切正常,如果我点击“打开”content://com.kaitenmail.attachmentprovider/[-0-9a-f]*/[0-9]*/VIEW匹配 %APP_HOME%\lib\* 并且我遇到了上述错误。

2 个答案:

答案 0 :(得分:0)

显然有两种方法:

  1. 可以致电

    Context.checkCallingUriPermission(Uri uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
    

    检查是否允许调用进程写入给定的Uri

    对于我可以检查的情况,在API级别< 19只要写入指向PackageManager.PERMISSION_DENIED的输出流失败,并且在所有其他情况下都在uri,这似乎会导致PackageManager.PERMISSION_GRANTED

    对于API级别> = 19,即使之前已使用PackageManager.PERMISSION_DENIED获得持久写入权限,也会产生getContentResolver().takePersistableUriPermission(Uri uri, int takeFlags)。在那种情况下,可以使用

    context.getContentResolver().getPersistedUriPermissions()
    

    获取所有以前获取的权限的列表,然后查看它们,看看是否有权写入给定的Uri

  2. 如果通过Uri获得了Intent intent,可以通过intent.getFlags()检查其标记,看看是否设置了Intent.FLAG_GRANT_WRITE_URI_PERMISSION。这似乎也是预测未来的一种方式"。

  3. 显然,上述方法都不能成为不能正确处理写入流时可能发生的异常的借口。

答案 1 :(得分:0)

测试任何资源是否可用的正确方法是尝试使用它,并处理在不能使用时产生的异常或错误。

其他任何事都等于算命。你可能

  • 测试错误的东西
  • 测试正确的东西,但得到的答案在测试时是正确的,但在实际使用时没有。这可以有两种方式,都是坏的:测试说你不能,但后来你可以:或者测试说你可以,但以后你就可以了。

不要试图预测未来。应对现在是很困难的。