如何知道写入流是否会导致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)
例外,这里有很多帖子,但是似乎没有一个可以回答我的特定问题:
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.
推荐答案
显然有两种方法:
-
一个可以打电话
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屋!