Android文件选择器获URI后,如何通过fd在NDK的C中用fopen打开文件?
问题解答
1. 文件描述符是什么?
文件描述符是操作系统内核用来标识已打开文件的整数型标识,相当于应用与内核之间的"文件操作句柄"。系统通过它跟踪文件的读写位置、权限状态等核心信息,是比文件路径更底层的文件操作标识。
2. 能否通过文件描述符获取文件路径?
不能。从文件选择器获取的共享文件(如DocumentsProvider提供的文件),很多情况下没有真实的本地文件路径(比如云端文件、沙箱隔离文件),系统也不会暴露真实路径给应用。即使是本地文件,通过描述符反向推导路径的操作不仅不可靠,还会被Android权限机制限制。
3. C代码是否具备该文件的读写权限?
具备。你通过getContentResolver().openFileDescriptor(uri, "w")获取的文件描述符,已经附带了用户选择文件时授予的对应权限(你传入的"w"代表写入权限,若需要读取可传"r"或"rw")。C层直接使用该描述符时,会继承这个权限,无需额外申请系统权限。
4. 如何在C代码中使用该文件描述符?
无需获取文件路径,直接用C标准库的fdopen()函数,将文件描述符转换为FILE*指针,即可像fopen()返回的指针一样进行操作:
实现步骤
- 通过JNI将Java层的
FileDescriptor传递到C层,用GetIntField方法提取对应的整数型描述符。 - 在C层调用
fdopen()完成转换:
#include <stdio.h> // 假设从JNI拿到的文件描述符为int fd FILE* file = fdopen(fd, "w"); // 模式需与Java层openFileDescriptor的模式对应 if (file != NULL) { // 执行读写操作,例如fprintf、fwrite等 fprintf(file, "Write from NDK"); fclose(file); // 关闭FILE*时会同时关闭文件描述符,注意不要在Java层重复关闭pfd }
注意事项
- 确保传递到C层的文件描述符处于有效状态,未被Java层提前关闭。
fdopen()的模式参数需与Java层openFileDescriptor的模式匹配(例如Java传"rw",C可使用"r+")。- 若C层调用
fclose(file)关闭了文件指针,Java层不要再调用pfd.close(),避免重复关闭引发错误。
内容的提问来源于stack exchange,提问作者Mary
相关产品推荐
相关产品推荐

