Android 中的持久文件描述符

问题描述 投票:0回答:2

我正在编写一个 Android 应用程序,用于管理文件并与其他应用程序共享它们。该应用程序实现了一个内容提供程序,该内容提供程序将

ParcelFileDescriptor
对象分发给请求应用程序(就像内置的电子邮件应用程序和 K-9 邮件应用程序所做的那样):

   public ParcelFileDescriptor openFile(Uri uri, String mode)
        throws FileNotFoundException {
    File file;      
    ...

    file = new File(FilePermsActivity.FILE_ROOT, fileName);         
    ParcelFileDescriptor fd;        
    fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);         
    // store the file descriptor for later
    String callerPackage = getAppNameByPID(getContext(), Binder.getCallingPid());       
    FilesApplication.getInstance().addFd(callerPackage, fd);            
    return fd;
}

我想允许文件管理器稍后关闭文件描述符,以防止两个应用程序同时持有打开的读+写文件描述符。

FilesApplication
类执行此操作,存储
ParcelFileDescriptor
对象以供以后使用:

    public void addFd(String packageName, ParcelFileDescriptor fd) {
    List<ParcelFileDescriptor> fds = null; 

    if ( openFds.containsKey(packageName))
    {
        fds = openFds.get(packageName);
        fds.add(fd);
    }       
    else
    {
        fds = new ArrayList<ParcelFileDescriptor>();
        fds.add(fd);
        openFds.put(packageName, fds);
    }           
}

public List<ParcelFileDescriptor> getFds (String packageName) {
    return openFds.get(packageName);
}

问题是,当我尝试使用

ParcelFileDescriptor
检索打开的
getFds
时,文件描述符始终无效。通过检查,接收方应用程序仍然可以使用之前发送的文件描述符,但我的应用程序无法关闭它。

是否有什么因素阻碍了

ArrayList
中的存储以及随后的文件描述符检索?

android persistence file-descriptor
2个回答
0
投票

经过更多搜索,问题不是

ParcelFileDescriptor
,因为无论我用哪个容器盛放它(
ArrayList
,常规
ParcelFileDescriptor[]
),它都会失效。我能找到的最好的解释是 ContentProvider 的文档说:

返回的 ParcelFileDescriptor 归调用者所有,因此他们有责任在完成后关闭它。也就是说,该方法的实现应该为每次调用创建一个新的 ParcelFileDescriptor。

我想这意味着调用者获得对返回的文件描述符的独占控制权,并且我的应用程序以后无法关闭它。


0
投票

您可以自己使用ParcelFileDescriptor的文件描述符,但您首先需要调用

detachFd()
(1),因此您明确告诉系统您负责关闭FileDescriptor。

int fd = fileDecriptor.detachFd();

detachFd()
返回与本机文件描述符 ID 相对应的
int

完成后,您必须关闭文件描述符:

close(fd);
© www.soinside.com 2019 - 2024. All rights reserved.