我的Android进阶之旅------>/storage/sdcard0, /sdcard, /mnt/sdcard ,/storage/emulated/legacy 的区别-阿里云开发者社区

开发者社区> 欧阳鹏> 正文

我的Android进阶之旅------>/storage/sdcard0, /sdcard, /mnt/sdcard ,/storage/emulated/legacy 的区别

简介: 转自:http://bbs.gfan.com/android-5382920-1-1.html 关于android的4.2的0文件夹的详解---- android 4.0 ----在galaxy nexus(GN)手机上userdata分区很大,被挂在/data目录,用户的数据通常是放在sd卡上,然而gn是没有sd卡的,所以google想了一个办法,就是虚拟一个。
+关注继续查看

转自:http://bbs.gfan.com/android-5382920-1-1.html

关于android的4.2的0文件夹的详解

---- android 4.0 ----
在galaxy nexus(GN)手机上userdata分区很大,被挂在/data目录,用户的数据通常是放在sd卡上,然而gn是没有sd卡的,所以google想了一个办法,就是虚拟一个。

所以,在userdata分区下有个目录叫media,是内置sd卡的数据存储位置,使用fuse技术将/data/media虚拟成为一个叫做/dev/fuse的设备,为了让程序能认出来,被同时挂载在 /mnt/sdcard 目录,
又为了兼容以前的程序,做了一个快捷方式(linux系统里叫软连接) /sdcard 指向的是 /mnt/sdcard .

当然,这些都是4.0的做法。

---- android 4.1 ---- 
在4.1里,同样也会使用fuse技术,/dev/fuse 会被同时挂载到/storage/sdcard0 目录,这个sdcard0表示第一个sd卡(如果有外置sd卡,那会多一个 /storage/sdcard1,比如我的xoom), /sdcard 软连接会指向 /storage/sdcard0 ,此时/mnt/sdcard 也是个软连接,会指向/storage/sdcard0。
如果你通过otg线接U盘,会被挂载到 /storage/usb0目录,stickmount这个软件为了让图库、快图、mx player等软件,能看到u盘里的数据,又同时挂载到 /storage/sdcard0/usStorage/sda1.

也许你会问,为什么不是usb0,而是sda1,这是linux的对硬盘的命名方式,如果你的u盘有多个分区,就分别是sda1,sda2这样一直排下去了。

---- android 4.2 ---- 
好了,我们开始说4.2系统。

谷歌是不是没事干啊,非要给android搞个多用户,你想想啊,在中国,可能因为经济问题,家里不是每人一个电脑,在美国,几乎需要用电脑的人,都会自己有一台或多台,一台电脑多人用的情况少之又少,这就是为什么叫PC了,顾名思义,个人电脑。像手机和平板这些东西,更加私人化了,很少公用了吧,我想在中国也是如此吧。

当然,谷歌也不完全是抽风,因为他有更大的战略部署,而且平板也的确有多人用的可能。

所以谷歌搞出来一个多用户,那每个人的应用、数据、个性配置都要分开吧。 应用和个性配置好弄,想想啊,通过权限控制,每人只能看自己的应用就行了,桌面也可以用自己的。

那数据怎么办????

好吧,调整用户数据的挂载结构。android 4.2,同样也会使用fuse技术/dev/fuse 会被挂载到/storage/emulated/0 目录,为什么是0呢,你还记得上边的sdcard0吧,第一个的意思。(如果有第二个,应该就是/storage/emulated/1,我们的三儿子没有外置sd卡,所以没法验证)

为了兼容以前,同时挂载到 /storage/emulated/legacy (故名思议,传统的),还建立三个软连接 /storage/sdcard0 ,/sdcard,/mnt/sdcard ,都指向  /storage/emulated/legacy

还有值得一提的是,4.2刚出来,这块变动又比较大,所以stickmount要升级到2.2之后,才可以通过otg挂载u盘了

所以大家不用为0而苦恼了,这是正常的“生理特征”

也许你会问,这个0和多用户有什么关系呢,那是因为多用户这个新特性,只在平板上才启用,在手机上会被禁用的。但是底层实现是一致的。 /mnt/shell/emulated 目录和 /storage/emulated 下的文件夹是一样的。(注意,这个/mnt/shell/emulated  不是挂载出来的)

由于我没有平板升级到4.2,所以只是推测,/mnt/shell/ 是为了多用户准备的,因为linux的多用户是基于shell实现的。

----------------2013-01-13-补充------------------------------------------------
4.2 在平板上的多用户
我前一段时间给XOOM Wifi刷上了CM10.1的4.2.1,成功开启多用户特性。新建的用户id从10开始。
默认用户的sdcard目录: /storage/emulated/0
新建的第一个用户的sdcard目录:  /storage/emulated/10
新建的第二个用户的sdcard目录:  /storage/emulated/11

关于0/0/0/0文件夹问题
是旧版本的CMW recovery在执行wipe data时导致建立新的0文件夹,请升级到cmw recovery 6.0.1.9 之后的版本,至于已经出现了多层0目录,请用RootExplorer剪切粘贴回/storage/emulated/0 下,推荐使用最新版CMW recovery 



===============转自:http://blog.csdn.net/gxj1680/article/details/8900270==================================================

最近的手机助手碰到一些关于sdcard目录的问题,特记下来以作备忘

在android 4.2版本之前,通过Environment.getExternalStorageDirectory()获取的sdcard默认目录是正常的,可进行读写,一般的结果是“/mnt/sdcard”,但是在4.2版本之后,获取的sdcard目录是“/storage/emulated/0”,使用File.exist()方法返回true表示文件/目录是存在的,但是通过adb向该返回的目录中写数据(上传文件=)是不成功的,返回的错误是"No such file or directory",个人判断是返回的路径“/storage/emulated/0”其实是个类似快捷方式的文件,通过特定的解析方式可以认为是目录,但对于adb来说,该路径就是个文件,adb没有做过多的属性=判断。上述判断也是有依据的,通过adb的shell命令获取指定目录下的文件/文件夹列表, 该路径显示的是文件,且有大小。


之前就有猜测,关于目录结构中会存在不同程度的虚拟链接文件,google了下确实如此,以下的3处虚拟符号链接(类似windows下的快捷方式)是:

"/storage/emulated/0 and /storage/emulated/0/0 (new and "backup" locations, respectively)
/storage/emulated/legacy and /storage/emulated/legacy/0 (new and "backup" locations, respectively)
/storage/sdcard0 and /storage/sdcard0/0 (new and "backup" locations, respectively)" (文章链接是http://androidforums.com/verizon-galaxy-nexus-all-things-root/649940-4-2-sdcard-sdcard-0-observation.html)


所以在处理sdcard目录时,尽量自己先判断处理后提供同一的接口

[java] view plaincopy
  1. import java.io.File;  
  2.   
  3. import android.os.Environment;  
  4. import android.text.TextUtils;  
  5.   
  6. public class CommonData {  
  7.   
  8.     private static String CD_S_SdcardPath = "";  
  9.     private static String CD_S_SdcardPathAbsolute = "";  
  10.       
  11.     public static String getSdcardPath(){  
  12.         if (TextUtils.isEmpty(CD_S_SdcardPath))  
  13.             CD_S_SdcardPath = Environment.getExternalStorageDirectory().getPath();  
  14.   
  15.         if (CD_S_SdcardPath.contains(CommonType.CT_S_Sdcard_Sign_Storage_emulated))  
  16.             CD_S_SdcardPath = CD_S_SdcardPath.replace(CommonType.CT_S_Sdcard_Sign_Storage_emulated, CommonType.CT_S_Sdcard_Sign_Storage_sdcard);  
  17.   
  18.         return CD_S_SdcardPath;  
  19.     }  
  20.   
  21.     public static String getAbsoluteSdcardPath(){  
  22.         if (TextUtils.isEmpty(CD_S_SdcardPathAbsolute))  
  23.             CD_S_SdcardPathAbsolute = Environment.getExternalStorageDirectory().getAbsolutePath();  
  24.   
  25.         if (CD_S_SdcardPathAbsolute.contains(CommonType.CT_S_Sdcard_Sign_Storage_emulated))  
  26.             CD_S_SdcardPathAbsolute = CD_S_SdcardPathAbsolute.replace(CommonType.CT_S_Sdcard_Sign_Storage_emulated, CommonType.CT_S_Sdcard_Sign_Storage_sdcard);  
  27.   
  28.         return CD_S_SdcardPathAbsolute;  
  29.     }  
  30.       
  31.     public static File getSdcardPathFile(){  
  32.         return new File(getSdcardPath());  
  33.     }  
  34.       
  35.     public static String checkAndReplaceEmulatedPath(String strSrc){  
  36.         if (strSrc.contains(CommonType.CT_S_Sdcard_Sign_Storage_emulated))  
  37.             strSrc = strSrc.replace(CommonType.CT_S_Sdcard_Sign_Storage_emulated, CommonType.CT_S_Sdcard_Sign_Storage_sdcard);  
  38.           
  39.         return strSrc;  
  40.     }  
  41. }  
其中

[java] view plaincopy
  1. public static final String CT_S_Sdcard_Sign_Storage_emulated = "storage/emulated/";  
  2. public static final String CT_S_Sdcard_Sign_Storage_sdcard = "storage/sdcard";  

获取sdcard目录时,统一有该类提供,以便兼容4.2的sdcard目录


注:至于通过Environment.getExternalStorageDirectory()获取的目录不能写入的问题,原因还不清楚,如果你知道,请告知,谢谢

注:以上是个人观察所得,难免有错误,如知晓,请告知



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//2013.05.10修正,关于目录/storage/emulated/legacy/目录的问题

因为google在4.2中考虑多用户的问题,对每个用户(user)来说,看各自的文件夹可以,但对于数据文件夹的处理就稍微麻烦了,所以调整了数据的挂载结构,如使用fuse技术/dev/fuse 会被挂载到/storage/emulated/0 目录,为了兼容以前,同时挂载到 /storage/emulated/legacy (故名思议,传统的),还建立三个软连接 /storage/sdcard0 ,/sdcard,/mnt/sdcard ,都指向  /storage/emulated/legacy/,(链接参见:http://bbs.gfan.com/android-5382920-1-1.html),但是就可能造成获取文件目录中的文件(如image)时,会出现相同的图片(本来上传1张,但出现了2张==)

将上面的类的判断修改如下

[java] view plaincopy
  1. public class CommonData {  
  2.   
  3.     private static String CD_S_SdcardPath = "";  
  4.     private static String CD_S_SdcardPathAbsolute = "";  
  5.       
  6.     public static String getSdcardPath(){  
  7.         if (TextUtils.isEmpty(CD_S_SdcardPath))  
  8.             CD_S_SdcardPath = Environment.getExternalStorageDirectory().getPath();  
  9.   
  10.         CD_S_SdcardPath = checkAndReplaceEmulatedPath(CD_S_SdcardPath);  
  11.   
  12.         return CD_S_SdcardPath;  
  13.     }  
  14.   
  15.     public static String getAbsoluteSdcardPath(){  
  16.         if (TextUtils.isEmpty(CD_S_SdcardPathAbsolute))  
  17.             CD_S_SdcardPathAbsolute = Environment.getExternalStorageDirectory().getAbsolutePath();  
  18.   
  19.         CD_S_SdcardPathAbsolute = checkAndReplaceEmulatedPath(CD_S_SdcardPathAbsolute);  
  20.   
  21.         return CD_S_SdcardPathAbsolute;  
  22.     }  
  23.       
  24.     public static File getSdcardPathFile(){  
  25.         return new File(getSdcardPath());  
  26.     }  
  27.       
  28.     public static String checkAndReplaceEmulatedPath(String strSrc){  
  29.       
  30.         <span style="color:#ff0000;">Pattern        p = Pattern.compile("/?storage/emulated/\\d{1,2}");  
  31.         Matcher     m = p.matcher(strSrc);  
  32.         if (m.find()){  
  33.             strSrc = strSrc.replace(CommonType.CT_S_Sdcard_Sign_Storage_emulated, CommonType.CT_S_Sdcard_Sign_Storage_sdcard);  
  34.         }</span>  
  35.           
  36. //      if (strSrc.contains(CommonType.CT_S_Sdcard_Sign_Storage_emulated) && !CD_S_SdcardPath.contains(CommonType.CT_S_Sdcard_Sign_Storage_emulated_legacy))  
  37. //          strSrc = strSrc.replace(CommonType.CT_S_Sdcard_Sign_Storage_emulated, CommonType.CT_S_Sdcard_Sign_Storage_sdcard);  
  38.           
  39.         return strSrc;  
  40.     }  
  41. }  


另外,针对image的上传后通过provider获取image图片时同一张图片给了2份,地址分别是"/storage/emulated/legacy/dcim/camera/1.jpg"和"/storage/sdcard0/DCIM/Camera/1.jpg",其中legacy的属于兼容的,但获取能获取出来,所以获取时要进行过滤处理



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

http://android.stackexchange.com/questions/39542/confused-by-the-many-locations-of-the-virtual-sdcard

public static final String SDPATH = Environment .getExternalStorageDirectory().getAbsolutePath();
//获取外部存储的路径返回绝对路径的,其实就是你的SD卡的文件路径

 

/storage/sdcard
/sdcard
/mnt/sdcard

以上三者的区别?

/sdcard是/mnt/sdcard的符号链,指向/mnt/sdcard,

/storage/sdcard 是sdcard的分区……

 

/sdcard/: this is a symlink to...
/mnt/sdcard (Android < 4.0)
/storage/sdcard0 (Android 4.0+)

 

  • /storage/emulated/0/: to my knowledge, this refers to the "emulated MMC" ("owner part"). Usually this is the internal one. The "0" stands for the user here, "0" is the first user aka device-owner. If you create additional users, this number will increment for each.
  • /storage/emulated/legacy/ as before, but pointing to the part of the currently working user (for the owner, this would be a symlink to /storage/emulated/0/). So this path should bring every user to his "part".
  • /sdcard/: According to a comment by Shywim, this is a symlink to...
    • /mnt/sdcard (Android < 4.0)
    • /storage/sdcard0 (Android 4.0+)
  • /storage/sdcard0/: As there's no legacy pendant here (see comments below), the "0" in this case rather identifies the device (card) itself. One could, eventually, connect a card reader with another SDCard via OTG, which then would become /storage/sdcard1 (no proof for that, just a guess -- but I'd say a good one)

 

internal storage - Confused by the many locations of the virtual /sdcard/ - Android Enthusiasts Stack Exchange



        ====================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址http://blog.csdn.net/ouyang_peng

====================================================================================

 

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【我的Android进阶之旅】推荐一款能提升数十倍效率的Android应用开发助手
一功能介绍 a调试相关 1布局边界 2布局更新 3强制GPU渲染 4GPU渲染 5指针位置 6严格模式 7不保留应用 8不锁定屏幕 9开发者选项 10系统设置 11语言设置 12USB调试 b UI相关 13屏幕信息 14标准尺寸 c 信...
1012 0
【转】Virtual 与 abstract 区别之我见
Virtual 与 abstract 区别之我见 原文:http://www.cnblogs.com/wyjgreat/archive/2011/06/07/2074182.html    1.abstract方法只能在抽象类中声明,虚方法则不是。
821 0
Android下Context、Application、Activity之间的联系和区别
  在开发Android程序的时候,我们经常要跟Context、Activity、Application这三个类打交道,那么这个三个类之间有什么联系和区别呢?   首先Activity和Application都是Context的子类。Context从字面上理解就是上下文的意思,在实际应用中它也确实是起到了管理上下文环境中各个参数和变量的总用,方便我们可以简单的访问到各种资源。虽然
1031 0
Oracle中会话与事务有什么区别?
        一个会话可以启动多个事务,会话是session,指一次连接。         事务是指一个操作单元,要么成功,要么失败,没有中间状态。         会话中可以完成多个事务。 例如:         会话好比,在应用程序中连接数据库要执行连接,然后会关闭,这算一次会话。         事务呢,就好比在打开会话后要执行程序中的某一个或多个对数据库进行的操作。
673 0
【我的Android进阶之旅】 解决bug: Expected file scheme in URI: content://downloads/my_downloads/12
一、错误描述 今天测试MM用HTC手机测试某个模块的时候crash了,抓log后发现是使用DownloadManager下载apk安装包然后自动安装的时候,抛了异常:java.
1804 0
react 和 ractive的区别
前面进项目的时候同事说项目在用react. 我没有深究,实际中发现是ractive.js。后来发现其实另有一个react.js。和ractive.js是有区别的。不过也有相似的地方。 react项目的主页在http://facebook.github.io/react, react的目的和实现方式和ractive是相似的。
960 0
【我的Android进阶之旅】解决Center OS 64位系统编译Android APP报错error=2和finished with non-zero exit value 127
一、错误描述 1、问题 java.io.IOException: error=2, 没有那个文件或目录 今天在刚重新搭建好的64位的Center OS上安装好了Android SDK,Jenkins,Git等一系列用于持续集成的环境之后,准备编译下项目试一试,然后Jenkins编译失败,错误如下所示: Caused by: java.
1648 0
+关注
欧阳鹏
一个人,如果你不逼自己一把,你根本不知道自己有多优秀! Talk is cheap, show me the code.
456
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载