文章
- Android文件管理器选择文件,获得文件路径URI转File
- Android uri 转换文件路径
- Android 接收微信、QQ其他应用打开,第三方分享
- 与其他应用交互
- 从其他应用接收简单的数据
- android10以上 uri转file uri转真实路径
- Android中Uri和path file三者的相互转换
- How to get the Full file path from URI | Newbedev
- Get File Path From URI in Android JAVA - Handy Opinion
- 检索文件信息 | Android 开发者 | Android Developers
- android - Get filename and path from URI from mediastore - Stack Overflow
验证
1. 通过Uri -> FileDescriptor -> FileInputStream -> FileChannel
实在是想获取别的进程用FileProvider传过来的Uri对应的路径,
那就通过int fd = getContentResolver().openFileDescriptor().getFd()方法获取文件描述符,
然后获取/proc/{pid}/fd/{fd}文件的getCanonicalPath(),
或者是native中用readklink()方法,可以拿到Uri对应文件的绝对路径
java\io\FileInputStream.java
public FileChannel getChannel() {
synchronized (this) {
if (channel == null) {
channel = FileChannelImpl.open(fd, path, true, false, this);
}
return channel;
}
}
-
通过其他APP分享数据,当前APP解析其Uri,可以获取Uri实际关联的文件对应的FileInputStream -> FileChannel .
try {
var f1: File = File(it.path)
var f2: File = File(it.toString())
LogUtils.d(TagConstants.URI_TO_FILE, "f1 correct:" + f1.exists() + " ; f2 correct:" + f2.exists())
LogUtils.d(TagConstants.URI_TO_FILE, "f1 correct:" + f1.absolutePath + " ; f2 correct:" + f2.absolutePath)
} catch (e: Exception) {
LogUtils.d(TagConstants.URI_TO_FILE, "gain file error. err:" + e.message)
}
try {
LogUtils.d(TagConstants.URI_TO_FILE, "gain fd.");
var fd: FileDescriptor? = contentResolver.openFileDescriptor(it,"r")?.fileDescriptor
var fi: FileInputStream? = null;
if(fd != null){
LogUtils.d(TagConstants.URI_TO_FILE, "gain fi.")
fi = FileInputStream(fd)
LogUtils.d(TagConstants.URI_TO_FILE, "gain fc.")
var fc:FileChannel = fi.channel
if(fc == null){
LogUtils.d(TagConstants.URI_TO_FILE, "gain fc. fc is null.")
}else{
LogUtils.d(TagConstants.URI_TO_FILE, "gain fc. fc is not null.")
}
}else{
LogUtils.d(TagConstants.URI_TO_FILE, "gain fc. fd is null.")
}
} catch (e: Exception) {
LogUtils.d(TagConstants.URI_TO_FILE, "gain fc. err:" + e.message)
e.printStackTrace()
}
2021-09-16 01:14:08.324 15897-15897 D/TagUriToFile: f1 correct:false ; f2 correct:false
2021-09-16 01:14:08.324 15897-15897 D/TagUriToFile: f1 correct:/2/352 ; f2 correct:/content:/com.google.android.apps.nbu.files.provider/2/352
2021-09-16 01:14:08.324 15897-15897 D/TagUriToFile: gain fd.
2021-09-16 01:14:08.331 15897-15897 D/TagUriToFile: gain fi.
2021-09-16 01:14:08.331 15897-15897 D/TagUriToFile: gain fc.
2021-09-16 01:14:08.331 15897-15897 D/TagUriToFile: gain fc. fc is not null.
2021-09-16 01:14:08.347 15897-15897 D/TagUriToFile: f1 correct:false ; f2 correct:false
2021-09-16 01:14:08.347 15897-15897 D/TagUriToFile: f1 correct:/2/36 ; f2 correct:/content:/com.google.android.apps.nbu.files.provider/2/36
2021-09-16 01:14:08.347 15897-15897 D/TagUriToFile: gain fd.
2021-09-16 01:14:08.350 15897-15897 D/TagUriToFile: gain fi.
2021-09-16 01:14:08.350 15897-15897 D/TagUriToFile: gain fc.
2021-09-16 01:14:08.350 15897-15897 D/TagUriToFile: gain fc. fc is not null.
2021-09-16 01:14:08.363 15897-15897 D/TagUriToFile: f1 correct:false ; f2 correct:false
2021-09-16 01:14:08.363 15897-15897 D/TagUriToFile: f1 correct:/2/29 ; f2 correct:/content:/com.google.android.apps.nbu.files.provider/2/29
2021-09-16 01:14:08.363 15897-15897 D/TagUriToFile: gain fd.
2021-09-16 01:14:08.366 15897-15897 D/TagUriToFile: gain fi.
2021-09-16 01:14:08.366 15897-15897 D/TagUriToFile: gain fc.
2021-09-16 01:14:08.366 15897-15897 D/TagUriToFile: gain fc. fc is not null.
2021-09-16 01:14:08.378 15897-15897 D/TagUriToFile: f1 correct:false ; f2 correct:false
2021-09-16 01:14:08.379 15897-15897 D/TagUriToFile: f1 correct:/2/28 ; f2 correct:/content:/com.google.android.apps.nbu.files.provider/2/28
2021-09-16 01:14:08.379 15897-15897 D/TagUriToFile: gain fd.
2021-09-16 01:14:08.382 15897-15897 D/TagUriToFile: gain fi.
2021-09-16 01:14:08.383 15897-15897 D/TagUriToFile: gain fc.
2021-09-16 01:14:08.383 15897-15897 D/TagUriToFile: gain fc. fc is not null.
2. 验证直接通过Uri获取InputStream和Uri->FileDescriptor->FileInputStream,两者读取效率差异
- 从log看两者读取效率无明显差异.
//1:
// FileDescriptor fd = contentResolver.openFileDescriptor(uri,"r").getFileDescriptor();
// FileInputStream fi = new FileInputStream(fd);
2021-09-24 17:00:59.331 28244-28283 D/TagUriPath: getFileSize. FileInputStream.curr: 1048576
2021-09-24 17:01:08.795 28244-28283 D/TagUriPath: getFileSize. FileInputStream.curr: 7181312198
2021-09-24 17:01:08.796 28244-28283 D/TagUriPath: getFileSize. FileInputStream <= -1. break.
//2: testIs = context.getApplicationContext().getContentResolver().openInputStream(uri);
2021-09-24 17:03:31.378 28639-28639 D/TagUriPath: getFileSize. fileSize:7181312198
2021-09-24 17:03:31.388 28639-28639 D/TagUriPath: getFileSize. is.start. FileInputStream.total: 0
2021-09-24 17:03:42.381 28639-28639 D/TagUriPath: getFileSize. is.end. FileInputStream.total: 7181312198
从log上,可见读取7G左右的文件,直接使用InputStream和得到FileDescriptor再转FileInputStream,读取效率很接近.