如何知道写入流是否会导致java.io.IOException:写入失败:EBADF(错误的文件号) [英] How to know whether writing to stream would result in java.io.IOException: write failed: EBADF (Bad file number)

查看:922
本文介绍了如何知道写入流是否会导致java.io.IOException:写入失败:EBADF(错误的文件号)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道关于java.io.IOException: write failed: EBADF (Bad file number)例外,这里有很多帖子,但是似乎没有一个可以回答我的特定问题:

I know there are a number of posts here on the java.io.IOException: write failed: EBADF (Bad file number) exception, but non of them seems to answer my particular question:

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

Suppose my activity is called with Intent.ACTION_VIEW and I got a Uri via Uri uri = intent.getData() that starts with content:// from which I read some data (for example a pdf file). Now I want to find out whether I can also write to that Uri to decide whether a "save" button should be shown to the user, or just a "save as" button.

进一步假设我可以像在

ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "w");
FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());

这样的fileOutputStream != null.

根据Uri现在可能发生,如果我尝试写fileOutputStream我会得到一个例外:

Depending on the Uri it can now happen that if I try to write to fileOutputStream I get the exception:

Exception=java.io.IOException: write failed: EBADF (Bad file number)

我想提前知道在不实际触摸/更改文件的情况下是否会发生这种情况.有人认为,应该可以在尝试之前找出我是否可以写给定的Uri.

I would like to know in advance whether this will happen without actually touching/changing the file. One would think that it should be possible to find out whether I can write to a given Uri or not before trying.

我该如何实现?

其他观察结果:

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

I suppose that the above happens when I don't have permission to write to that particular file/uri, but then why does Android let me open a FileOutputStream in the first place?

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

For testing I use attachments in emails received with Kaiten mail on an ICS device. If I my app opens after I click on "save" in Kaiten mail uri matches content://media/external/file/[0-9]* and everything works, if I however clicked on "open" uri matches content://com.kaitenmail.attachmentprovider/[-0-9a-f]*/[0-9]*/VIEW and I run into the above error.

推荐答案

显然有两种方法:

  1. 一个可以打电话

  1. One can call

Context.checkCallingUriPermission(Uri uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)

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

to check whether the calling process is allowed to write to a given Uri.

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

For the cases I could check, on API level < 19 this seems to result in PackageManager.PERMISSION_DENIED whenever the writing to an output stream pointing to uri fails and in PackageManager.PERMISSION_GRANTED in all other cases.

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

For API level >= 19 it however yields PackageManager.PERMISSION_DENIED even if one has previously taken a persisted write permission with getContentResolver().takePersistableUriPermission(Uri uri, int takeFlags). In that case however one can use

context.getContentResolver().getPersistedUriPermissions()

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

to get a list of all previously taken permissions and then look through them so see if one has permission to write to a given Uri.

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

If one got he Uri via an Intent intent one can check its flags via intent.getFlags() and see whether Intent.FLAG_GRANT_WRITE_URI_PERMISSION is set. This also seems to be a way to "predict the future".

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

Obviously, neither of the above methods can be an excuse to not properly handle exceptions that can occur while writing to the stream.

这篇关于如何知道写入流是否会导致java.io.IOException:写入失败:EBADF(错误的文件号)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆