zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

android用java和c实现查找sd卡挂载路径(sd卡路径)的方法

AndroidJAVA方法 实现 查找 路径 挂载 SD
2023-06-13 09:15:18 时间

方法一:

分析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);