在 Android 中持久化文件描述符 (Persisting File Descriptors in Android)


問題描述

在 Android 中持久化文件描述符 (Persisting File Descriptors in Android)

I am writing an Android app that manages files and shares them with other applications.  The application implements a content provider that hands out ParcelFileDescriptor objects to requesting applications (just like the built in Email app and K-9 Mail applications do):

   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;
}

I want to allow the file manager to close the file descriptors later to prevent two applications from holding open read+write file descriptors at once.  The FilesApplication class does that, storing the ParcelFileDescriptor objects for later use:

    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);
}

The problem is that when I try to retrieve the open ParcelFileDescriptors using the getFds, the file descriptor is always invalid.  From checking, the recipient application can still use the file descriptor sent before, but my application isn't able to close it.

Is there something preventing the storage in an ArrayList and subsequent retrieval of file descriptors?


參考解法

方法 1:

After more searching, the problem isn't the ParcelFileDescriptor since no matter which container I used to hold it (ArrayList, regular ParcelFileDescriptor[]), it got invalidated. The best explanation I can find is that the documentation for ContentProvider says:

  

The returned ParcelFileDescriptor is owned by the caller, so it is their responsibility to close it when done. That is, the implementation of this method should create a new ParcelFileDescriptor for each call.

I guess that means that the caller gets exclusive control over the returned file descriptor and my application can't later close it.

(by skokeskoke)

參考文件

  1. Persisting File Descriptors in Android (CC BY-SA 3.0/4.0)

#file-descriptor #persistence #Android






相關問題

在 Android 中持久化文件描述符 (Persisting File Descriptors in Android)

無法理解 select() 系統調用 (failure to understand select() system call)

文件描述符中實際存儲了多少信息? (How much information is actually stored in a file descriptor?)

為同一個文件描述符創建兩個文件是否定義明確? (Is creating two FILEs for the same file descriptor well-defined?)

Android文件描述符洩漏調試 (Android file descriptor leakage debuging)

C中的文件描述符分配 (File Descriptor Assignment in C)

在某些 linux 程序中關閉奇怪的描述符 (Strange descriptor closing in some linux programs)

c read() 導致錯誤的文件描述符錯誤 (c read() causing bad file descriptor error)

C中系統調用的文件句柄問題 (Filehandle issue with system call in C)

使用 copy_file_range 進行複制加速 (Copy acceleration with copy_file_range)

打開文件過多錯誤,但 99.5% 的 inode 是免費的 (Too many open files error but 99.5% inodes are free)

SIGPIPE 由於文件描述符和進程替換 (SIGPIPE due to file descriptors and process substitution)







留言討論