繁体   English   中英

如何知道是否写入流是否会导致java.io.IOException:写入失败:EBADF(错误的文件号)

[英]How to know whether writing to stream would result in java.io.IOException: write failed: EBADF (Bad file number)

我知道在java.io.IOException: write failed: EBADF (Bad file number)上有很多帖子java.io.IOException: write failed: EBADF (Bad file number)异常,但是似乎没有一个可以回答我的特定问题:

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

进一步假设我可以成功地首先打开一个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

我该如何实现?

其他观察:

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

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

显然有两种方法:

  1. 一个可以打电话

     Context.checkCallingUriPermission(Uri uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION) 

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

    对于情况下,我可以检查,在API级<19,这似乎导致PackageManager.PERMISSION_DENIED每当写入到输出流指向uri失败,并在PackageManager.PERMISSION_GRANTED在所有其他情况。

    对于> = 19的API级别,即使以前使用getContentResolver().takePersistableUriPermission(Uri uri, int takeFlags)获得了持久的写许可权,它也会产生PackageManager.PERMISSION_DENIED 但是在那种情况下,可以使用

     context.getContentResolver().getPersistedUriPermissions() 

    获取所有先前获得的权限的列表,然后仔细检查它们,以便查看是否有写给定Uri权限。

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

显然,以上两种方法都不能作为未正确处理写入流时可能发生的异常的借口。

测试任何资源是否可用的正确方法是尝试使用它,并处理无法使用时导致的异常或错误。

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

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

不要试图预测未来。 应对目前的困难已经足够了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM