我知道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\*
并且我遇到了上述错误。
答案 0 :(得分:0)
显然有两种方法:
可以致电
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
。
如果通过Uri
获得了Intent intent
,可以通过intent.getFlags()
检查其标记,看看是否设置了Intent.FLAG_GRANT_WRITE_URI_PERMISSION
。这似乎也是预测未来的一种方式"。
显然,上述方法都不能成为不能正确处理写入流时可能发生的异常的借口。
答案 1 :(得分:0)
测试任何资源是否可用的正确方法是尝试使用它,并处理在不能使用时产生的异常或错误。
其他任何事都等于算命。你可能
不要试图预测未来。应对现在是很困难的。