迁移至SAF后,如何替代C++ stat判断文件可写性?
解决方案
1. 在Java侧通过SAF查询文件可写性
SAF不依赖传统文件系统的rwx权限,需通过查询文档的COLUMN_FLAGS字段判断是否支持写入:
修改查询代码
在查询子文件时,新增DocumentsContract.Document.COLUMN_FLAGS字段到查询列中:
c = getContentResolver().query(childrenUri, new String[] { DocumentsContract.Document.COLUMN_DOCUMENT_ID, DocumentsContract.Document.COLUMN_DISPLAY_NAME, DocumentsContract.Document.COLUMN_MIME_TYPE, DocumentsContract.Document.COLUMN_FLAGS // 新增:获取文档权限标志 }, null, null, null);
判断文件可写性
在遍历Cursor时,解析COLUMN_FLAGS的值,通过FLAG_SUPPORTS_WRITE标识判断是否可写:
while (c.moveToNext()) { final String documentId = c.getString(0); final String documentName = c.getString(1); final int flags = c.getInt(3); // 对应新增的COLUMN_FLAGS字段 final Uri documentUri = DocumentsContract.buildDocumentUriUsingTree(uri, documentId); // 判断是否支持写入 boolean isWritable = (flags & DocumentsContract.Document.FLAG_SUPPORTS_WRITE) != 0; // 根据可写性选择打开模式,避免崩溃 String openMode = isWritable ? "rw" : "r"; try { ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(documentUri, openMode); int nativeFD = fd.detachFd(); // 将nativeFD和isWritable传递给C++侧 } catch (IOException e) { e.printStackTrace(); } folderContent.append(documentName + "\n"); }
2. C++侧可选的验证方式
如果需要在C++侧再次确认文件描述符的可写性,可通过fcntl获取文件状态标志判断:
#include <fcntl.h> #include <unistd.h> bool isFileWritable(int fd) { int statusFlags = fcntl(fd, F_GETFL); if (statusFlags == -1) { // 处理错误,比如perror("fcntl failed"); return false; } // 检查是否为可写或读写模式 return (statusFlags & O_WRONLY) != 0 || (statusFlags & O_RDWR) != 0; }
关键说明
- SAF的文档权限由文档提供者管理,传统
stat获取的文件属性无法反映SAF层面的可写性,必须通过ContentResolver查询文档标志。 - 打开文件时根据可写性选择对应模式,是避免
openFileDescriptor调用崩溃的核心。
内容的提问来源于stack exchange,提问作者user1063364
相关产品推荐
相关产品推荐

