我将在Android项目中使用FFmpeg作为JNI库,我知道Kitkat的局限性。由于新发布的Lollipop有可能第三方应用程序访问外部microsd我想利用它。我已阅读this useful question所以我使用ACTION_OPEN_DOCUMENT_TREE意图,用户选择一个文件夹,而不是使用类似的代码来获取文件描述符。然后我将此UNIX文件描述符发送到jni函数。我创建了一个演示,如果我使用这样的东西:
int descriptor = a_file_descriptor;
FILE* fp = fdopen(descriptor , "w");
fprintf(fp, "Hello from Lollipop!");
fclose(fp);
一切都很好。问题是我想从文件描述符中提取完整的文件名。有可能为Linux提供一些技巧,但如果我做一个fopen并尝试fprintf文件中的东西没有任何反应。所以我想我应该使用文件描述符,但如何在FFmpeg中使用它?我读到了pipe选项,但它似乎仅适用于命令行。在此先感谢您的帮助。
答案 0 :(得分:2)
问题是我想从文件描述符中提取完整的文件名。
是的,可以通过Linux上的小技巧从文件描述符中提取文件的完整路径。每个创建的进程都在/proc/[pid]
下有一个目录,您可以在进程目录/proc/[pid]
下找到有关进程的资源,包括打开的文件描述符。然后打开的文件描述符以/proc/[pid]/fd/[fd_number]
的形式存在,例如/proc/17059/fd/20
。这通常是指向真实文件路径的符号链接,因此我们可以通过解析符号链接来获取完整路径。
以下是在Linux上运行的演示代码。是的,它可以在Android上的JNI调用中使用。
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int fd;
char path[512] = { 0 };
char* real_path = NULL;
if ((fd = open("/tmp/test", O_CREAT | O_WRONLY)) == -1) {
fprintf(stderr, "open fail");
}
sprintf(path, "/proc/%d/fd/%d", getpid(), fd);
if (path[0] != '\0') {
printf("fd path is %s\n", path);
real_path = realpath(path, NULL);
if (real_path != NULL) {
printf("get full path from fd %s\n", real_path);
free(real_path);
}
}
exit(EXIT_SUCCESS);
}