android用java和c实现查找sd卡挂载路径(sd卡路径)的方法
方法一:
分析mount命令的返回信息,例如:
$mount
rootfs/rootfsro,relatime00
tmpfs/devtmpfsrw,nosuid,relatime,mode=75500
devpts/dev/ptsdevptsrw,relatime,mode=60000
proc/procprocrw,relatime00
sysfs/syssysfsrw,relatime00
debugfs/sys/kernel/debugdebugfsrw,relatime00
none/acctcgrouprw,relatime,cpuacct00
tmpfs/mnt/asectmpfsrw,relatime,mode=755,gid=100000
tmpfs/mnt/obbtmpfsrw,relatime,mode=755,gid=100000
none/dev/cpuctlcgrouprw,relatime,cpu00
/dev/block/platform/sdhci-tegra.3/by-name/system/systemext4ro,relatime,barrier=1,data=ordered00
/dev/block/platform/sdhci-tegra.3/by-name/userdata/dataext4rw,nosuid,nodev,noatime,barrier=1,data=ordered00
/dev/block/platform/sdhci-tegra.3/by-name/cache/cacheext4rw,nosuid,nodev,noatime,barrier=1,data=ordered00
/dev/block/platform/sdhci-tegra.3/by-name/pdsb/pdsext2ro,relatime00
/dev/fuse/mnt/sdcardfuserw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other00
/dev/block/vold/179:9/mnt/sdcard-extvfatrw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro00
/dev/block/vold/179:9/mnt/secure/asecvfatrw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro00
tmpfs/mnt/sdcard-ext/.android_securetmpfsro,relatime,size=0k,mode=00000
Java版代码如下:
//给C/C++编写的共享库回调取得全部SD卡路径的函数
publicString
GetAllSDPath()throwsTokenException
{
StringstrMountInfo="";
//1.首先获得系统已加载的文件系统信息
try
{
//创建系统进程生成器对象
ProcessBuilderobjProcessBuilder=newProcessBuilder();
//执行mount-h可以看到mount:listmountedfilesystems
//这条命令可以列出已加载的文件系统
objProcessBuilder.command("mount");//新的操作系统程序和它的参数
//设置错误输出都将与标准输出合并
objProcessBuilder.redirectErrorStream(true);
//基于当前系统进程生成器的状态开始一个新进程,并返回进程实例
ProcessobjProcess=objProcessBuilder.start();
//阻塞线程至到本地操作系统程序执行结束,返回本地操作系统程序的返回值
objProcess.waitFor();
//得到进程对象的输入流,它对于进程对象来说是已与本地操作系统程序的标准输出流(stdout)相连接的
InputStreamobjInputStream=objProcess.getInputStream();
byte[]buffer=newbyte[1024];
//读取mount命令程序返回的信息文本
while(-1!=objInputStream.read(buffer))
{
strMountInfo=strMountInfo+newString(buffer);
}
//关闭进程对象的输入流
objInputStream.close();
//终止进程并释放与其相关的任何流
objProcess.destroy();
}
catch(Exceptione)
{
e.printStackTrace();
}
//2.然后再在系统已加载的文件系统信息里查找SD卡路径
//mount返回的已加载的文件系统信息是以一行一个信息的形式体现的,
//所以先用换行符拆分字符串
String[]lines=strMountInfo.split("\n");
//清空该字符串对象,下面将用它来装载真正有用的SD卡路径列表
strMountInfo="";
for(inti=0;
i<lines.length;
i++)
{
//如果该行内有/mnt/和vfat字符串,说明可能是内/外置SD卡的挂载路径
if(-1!=lines[i].indexOf("/mnt/")&&//前面要有空格,以防断章取义
-1!=lines[i].indexOf("vfat")) //前后均有空格
{
//再以空格分隔符拆分字符串
String[]blocks=lines[i].split("\\s");//\\s为空格字符
for(intj=0;
j<blocks.length;
j++)
{
//如果字符串中含有/mnt/字符串,说明可能是我们要找的SD卡挂载路径
if(-1!=blocks[j].indexOf("/mnt/"))
{
//排除重复的路径
if(-1==strMountInfo.indexOf(blocks[j]))
{
//用分号符(;)分隔SD卡路径列表,
strMountInfo+=blocks[j]+";";
}
}
}
}
}
returnstrMountInfo;
}
C版代码如下:
charcaStdOutLine[1024];//mount命令的标准输出中的一行信息
char*pcTmpSDPath=NULL;
//再用mount命令获得的找身份认证锁
do//非循环,只是为了方便控制分支层次,便于控制分支流向
{
//通过创建一个管道,调用fork产生一个子进程,
//执行一个shell以运行命令来开启一个进程。
//这个进程必须由pclose()函数关闭。
FILE*fp=popen("mount",//一个指向以NULL结束的shell命令字符串的指针,
//这行命令将被传到bin/sh并使用-c标志,
//那么shell将执行这个命令从这个字符串中读取。
"r"); //文件指针连接到shell命令的标准输出
if(NULL==fp)
{
break;
}
while(NULL!=fgets(caStdOutLine,
sizeof(caStdOutLine),
fp))
{
//如果找到了你想要的SD卡挂载路径的话,则
if(判断条件)
{
//注:管道中的数据一定要读完,不然会崩溃掉的
continue;//就不再试下一个挂载地址了
}
//如果该行内有/mnt/和vfat字符串,说明可能是内/外置SD卡的挂载路径
if(NULL==strstr(caStdOutLine,"/mnt/")&& //前面要有空格,以防断章取义
NULL==strstr(caStdOutLine,"/storage/"))//前面要有空格,以防断章取义
{
continue;//不满足条件说明这行不是内/外置SD卡的挂载路径
}
if(NULL==strstr(caStdOutLine,"vfat")) //前后均有空格
{
continue;//不满足条件说明这行不是内/外置SD卡的挂载路径
}
//再以空格分隔符拆分字符串
pcTmpSDPath=strtok(caStdOutLine,"");
do//这里是循环,尝试每一个路径
{
if((NULL==pcTmpSDPath)||
("\0"==*pcTmpSDPath))
{
continue;
}
//如果字符串中含有/mnt/字符串,说明可能是我们要找的SD卡挂载路径
if(NULL==strstr(pcTmpSDPath,"/mnt/")&&
NULL==strstr(pcTmpSDPath,"/storage/"))
{
continue;
}
//TODO:在此添加对SD卡路径使用的语句,如果只是用其中一个,别忘了设置已找到想要SD卡路径的标识
}while(pcTmpSDPath=strtok(NULL,""));
}
//关闭标准I/O流,等待命令执行结束,然后返回shell的终止状态。
//如果shell不能被执行,
//则pclose()返回的终止状态与shell已执行exit一样。
pclose(fp);
}while(0);
方法二:
分析cat/system/etc/vold.fstab命令的返回信息,例如:
$cat/system/etc/vold.fstab
##Vold2.0fstabforStingray
#######################
##Regulardevicemount
##
##Format:dev_mount<label><mount_point><part><sysfs_path1...>
##label -Labelforthevolume
##mount_point -Wherethevolumewillbemounted
##part -Partition#(1based),or"auto"forfirstusablepartition.
##<sysfs_path>-Listofsysfspathstosourcedevices
######################
#externalsdcard
dev_mountsdcard-ext/mnt/sdcard-extauto/devices/platform/sdhci-tegra.2/mmc_host/mmc1/devices/platform/sdhci-tegra.2/mmc_host/mmc2
#flashdriveconnectiontoUSB1
dev_mountusbdisk_1.0/mnt/usbdisk_1.0auto/devices/platform/tegra-ehci.0/usb2/2-1/2-1:1.0
#flashdriveconnectionthroughhubconnectedtoUSB1
dev_mountusbdisk_1.1/mnt/usbdisk_1.1auto/devices/platform/tegra-ehci.0/usb2/2-1/2-1.1
dev_mountusbdisk_1.2/mnt/usbdisk_1.2auto/devices/platform/tegra-ehci.0/usb2/2-1/2-1.2
dev_mountusbdisk_1.3/mnt/usbdisk_1.3auto/devices/platform/tegra-ehci.0/usb2/2-1/2-1.3
dev_mountusbdisk_1.4/mnt/usbdisk_1.4auto/devices/platform/tegra-ehci.0/usb2/2-1/2-1.4
dev_mountusbdisk_1.5/mnt/usbdisk_1.5auto/devices/platform/tegra-ehci.0/usb2/2-1/2-1.5
dev_mountusbdisk_1.6/mnt/usbdisk_1.6auto/devices/platform/tegra-ehci.0/usb2/2-1/2-1.6
dev_mountusbdisk_1.7/mnt/usbdisk_1.7auto/devices/platform/tegra-ehci.0/usb2/2-1/2-1.7
C版代码如下:
charcaStdOutLine[1024];//cat命令的标准输出中的一行信息
char*pcTmpSDPath=NULL;
char*pcNotSpace=NULL;
//用/system/etc/vold.fstab获得的SD卡路径找身份认证锁
do//非循环,只是为了方便控制分支层次,便于控制分支流向
{
//通过创建一个管道,调用fork产生一个子进程,
//执行一个shell以运行命令来开启一个进程。
//这个进程必须由pclose()函数关闭。
FILE*fp=popen("cat/system/etc/vold.fstab",//一个指向以NULL结束的shell命令字符串的指针,
//这行命令将被传到bin/sh并使用-c标志,
//那么shell将执行这个命令从这个字符串中读取。
"r"); //文件指针连接到shell命令的标准输出
if(NULL==fp)
{
break;
}
while(NULL!=fgets(caStdOutLine,
sizeof(caStdOutLine),
fp))
{
//如果找到了你想要的SD卡挂载路径的话,则
if(判断条件)
{
//注:管道中的数据一定要读完,不然会崩溃掉的
continue;//就不再试下一个挂载地址了
}
//Format:dev_mount<label><mount_point><part><sysfs_path1...>
//去除开头的空格
pcNotSpace=caStdOutLine+strspn(caStdOutLine,"");
if(NULL==pcNotSpace ||
"\0"==*pcNotSpace ||
"#" ==*pcNotSpace ||//行首字符为#说明是注释行
"d"!=pcNotSpace[0]||//句子开头不是dev_mount
"e"!=pcNotSpace[1]||
"v"!=pcNotSpace[2]||
"_"!=pcNotSpace[3]||
"m"!=pcNotSpace[4]||
"o"!=pcNotSpace[5]||
"u"!=pcNotSpace[6]||
"n"!=pcNotSpace[7]||
"t"!=pcNotSpace[8])
{
continue;//不满足条件说明这行不是内/外置SD卡的挂载路径
}
//再以空格分隔符拆分字符串
pcTmpSDPath=strtok(pcNotSpace,"");
do//这里是循环,尝试每一个路径
{
if((NULL==pcTmpSDPath)||
("\0"==*pcTmpSDPath))
{
continue;
}
//如果字符串中含有/mnt/字符串,说明可能是我们要找的SD卡挂载路径
if(NULL==strstr(pcTmpSDPath,"/mnt/")&&
NULL==strstr(pcTmpSDPath,"/storage/"))
{
continue;
}
//TODO:在此添加对SD卡路径使用的语句,如果只是用其中一个,别忘了设置已找到想要SD卡路径的标识
}while(pcTmpSDPath=strtok(NULL,""));
}
//关闭标准I/O流,等待命令执行结束,然后返回shell的终止状态。
//如果shell不能被执行,
//则pclose()返回的终止状态与shell已执行exit一样。
pclose(fp);
}while(0);
相关文章
- android 置灰不可点击,Android Studio 运行按钮灰色的完美解决方法
- java判断一个对象是否为空_Java中判断对象是否为空的方法的详解
- java数组的声明_Java数组定义常用方法[通俗易懂]
- java语言的特点_Java语言有什么特点?
- java冒泡排序概练_Java的冒泡排序[通俗易懂]
- 在线学习Java的几个网站,别再盲目学习java了![通俗易懂]
- java dom4j 添加节点_Java dom4j获取,添加,删除,查找,设置Element节点方法「建议收藏」
- java中random方法取值范围_Java Random.nextInt()方法,随机产生某个范围内的整数
- Java版五子棋小游戏(java控制台)
- java notifyall_Java Thread notifyAll()方法[通俗易懂]
- java executeupdate_Java自学-JDBC execute与executeUpdate的区别
- Java截取字符串方法_java通过split截取字符串
- 【Android NDK 开发】JNI 方法解析 ( C/C++ 调用 Java 方法 | 函数签名 | 调用对象方法 | 调用静态方法 )
- 【错误记录】Android Studio 编译时 lint 检查报错 ( WARNING: DSL element ‘android.dataBinding.enabled‘ is obsolet )
- 【Android UI】贝塞尔曲线 ④ ( 使用 android.graphics.Path 提供的 cubicTo 方法绘制三阶贝塞尔曲线示例 )
- 利用Redis存储Java对象的方法(redis存储java对象)
- Linux下部署Java项目实践(linux部署java项目)
- 解析Java中的Linux路径(java中linux路径)