什么是/ storage / emulated / 0 /?


40

最近,我发现,如果我从中/sdcard/Download删除文件,则会从中删除文件/storage/emulated/0/Download。如果我将文件添加到/sdcard/Download其中,则会在中复制它们/storage/emulated/0/Download

那是什么/storage/emulated/0/?为了什么目的,我们在Android文件系统中拥有它?

Answers:


40

/storage/emulated/0/Download 是文件的实际路径。

/sdcard/Download 是到实际路径的符号链接 /storage/emulated/0/Download

但是,实际文件位于中的文件系统中/data/media,然后将其挂载到/storage/emulated/0(通常也挂载到其他挂载点)

符号连接在计算中,一个符号链接是包含在绝对或相对路径的形式的另一文件或目录的引用,并影响路径名解析任何文件的术语。到1978年,DEC和Data General的RDOS的微型计算机操作系统中已经存在符号链接。


15
如果它稍微解释了为什么它被“模拟”,那么这个答案会更好。我相信Android确实采取了一些伪造FAT fs的措施,而FAT fs实际上有更好的支持,但是我不知道具体细节,因此点击了这个问题,希望学到一些新知识。
R.,

4
@R ..“模拟”恕我直言指出了它是“模拟SD卡”(不是真实的SD卡)这一事实。
伊兹

10
@R.。它使用SDCardFS。这是一篇很棒的文章:xda-developers.com/…存档
Nonny Moose

16

/storage/emulated/0/实际上是/data/media/0/通过模拟/虚拟文件系统公开的,而不是实际的。

这是参考我以前的答案在这里,但更多的相关细节。

安卓存储

Android 5上

/sdcard >S> /storage/emulated/legacy >S> /mnt/shell/emulated/0
/mnt/shell/emulated >E> /data/media

Android 6+上

# for (Java) Android apps (running inside zygote virtual machine)
# "/storage to VIEW" bind mount is inside a separate mount namespace for every app
/sdcard >S> /storage/self/primary
/storage/self >B> /mnt/user/USER-ID
/mnt/user/USER-ID/primary >S> /storage/emulated/USER-ID
/storage/emulated >B> /mnt/runtime/VIEW/emulated
/mnt/runtime/VIEW/emulated >E> /data/media

# for services/daemons/processes in root/global namespace (VIEW = default)
/sdcard >S> /storage/self/primary
/storage >B> /mnt/runtime/default
/mnt/runtime/default/self/primary >S> /mnt/user/USER-ID/primary
/mnt/user/USER-ID/primary >S> /storage/emulated/USER-ID
/storage/emulated >B> /mnt/runtime/default/emulated
/mnt/runtime/default/emulated >E> /data/media

* >S>用于符号链接,>E>用于仿真和>B>用于绑定安装
* USER-ID当前用户(如果是Multiple Users或)Work Profile,通常0是设备所有者的
* VIEWread(对于具有许可权的应用程序。READ_EXTERNAL_STORAGE)或write(permission.WRITE_EXTERNAL_STORAGE)或default(对于在root中运行的进程之一/ global mount名称空间,即在zygote之外)
*与先前的Android版本略有不同,但是自实施以来,仿真的概念是相同的。
*有关Android的mount名称空间实现的更多详细信息,请参见此答案

简而言之,/sdcard并且/storage/emulated/0-代表FAT / vFAT / FAT32文件系统- 通过或仿真指向/data/media/0(或/mnt/expand/[UUID]/media/0采用存储的情况下)。 FUSEsdcardfs

符号链接绑定安装(请参阅“创建绑定安装”)不是特定于Android的,而是通常与Linux相关的,因此不在此问题的范围内,因为该问题主要是关于仿真部分的。

仿真:

为什么要在这里进行仿真?仿真文件系统是实际文件系统(ext4f2fs)上的抽象层,主要用于两个目的:

  • 保持Android设备与PC的USB连接(现在通过MTP实施)
  • 限制未经授权访问应用程序/进程到SD卡上用户的私有媒体和其他应用程序的数据。

阅读Android的存储之旅以了解详细信息,摘要为:

早期的Android设备内部存储空间不足,并且(物理上)依赖外部SD卡,这些SD卡传统上使用FAT系列文件系统来确保与大多数PC的兼容性(请参阅Microsoft在PC世界中的主导地位)。
当内部存储的容量增加时,相同的文件系统将移至内部(仍称为“外部”)SD卡。
但是FAT / vFAT实施存在两个主要问题,Google逐渐解决了这些问题:

  • 就像我们最近连接USB驱动器一样,Android设备直接连接到PC(USB大容量存储)。UMS在设备级别公开设备,并从Android框架断开SD卡的连接(卸载),从而使整个数据对应用程序不可用,并可能破坏许多功能。
  • FAT(即Windows的开发天的最爱)从未被设计来执行UNIX权限(模式,UID,GID和同样的符号链接,并ioctlsFS_IOC_FIEMAP)。因此,SD卡上的所有数据对所有应用程序都是可用的(因为每个Android应用程序都是UNIX / Linux用户且具有uid),没有任何限制,因此引发了严重的隐私和安全问题。

通过仿真解决了这两个问题:

  • 实际的SD卡存储已移至/data拥有ext4文件系统的分区(或以前在某些设备上的独立/ sdcard分区)(逐渐由取代f2fs),完全实现了UNIX权限。
  • 这种设计使使用UMS成为不可能,因为整个/data分区不能再暴露给PC有两个原因:(1)它包含许多设置和应用程序数据,这些数据将受到保护,免受其他应用程序和人类用户的攻击。(2)Windows不支持Linux文件系统。
    因此,UMS被Media Transfer Protocol替代,后者是PTP的客户端-服务器类型扩展-已经建立的协议。MTP不会公开块设备,而是通过软件堆栈工作。MTP主机在应用程序(android.process.media)上在Android上运行,而该应用程序()已在Android框架中完全沙箱化,无法执行任何升级任务。

现在,这些应用程序(以及MTP,也是一个应用程序)与模拟存储进行交互,而不是与/data/media,同时实现了这两个目的,即在下面强制执行权限检查,并看起来像FAT文件系统在上表面。

Google现在通过sdcardfs实现仿真,以克服FUSE的缺点;输入/输出开销(即提高读取/写入速度)是一个主要问题。

外部存储 权限:可以使用以下示例演示外部存储上公共和私有文件的
概念:安装Termux应用程序。 创建目录和。 创建文件和。 执行以下命令:

/sdcard/Android/data/com.termux/test_dir/sdcard/test_dir
/sdcard/Android/data/com.termux/test_file/sdcard/Android/data/com.termux/test_file

没有存储空间 *您应该已安装WhatsApp或选择其他一些应用程序的专用文件夹。

现在,强制停止Termux应用程序并授予存储权限。再次执行命令:

with_storage_perm

查看相同文件和目录的权限差异。当有数百个应用程序(用户)要同时处理时,如果没有在本地Linux文件系统上进行仿真,这似乎不可能简单地实现。这是文件系统仿真,它使同一文件可以同时以三组不同的权限公开,而与实际文件系统上的原始权限无关:

# touch /data/media/0/test_file

# stat -c '%a %u %g %n' /data/media/0/test_file
644 1023 1023 /data/media/0/test_file

# stat -c '%a %u %g %n' /mnt/runtime/*/emulated/0/test_file
660 0 1015 /mnt/runtime/default/emulated/0/test_file
640 0 9997 /mnt/runtime/read/emulated/0/test_file
660 0 9997 /mnt/runtime/write/emulated/0/test_file

另请参阅什么是“ u#_everybody” UID?

有关:


2
+1。我认为我误解了有关MTP的部分。MTP是否需要在目标设备上使用FAT文件系统才能使用?如果不是,那么Google不能将ext4文件系统用于FUSE实施,因为这样还可以强制执行应用程序访问共享存储中的数据所需的权限检查吗?
Firelord

1
@Firelord在讨论仿真时,重点不在MTP实现上。谷歌已经对MTP协议进行了更改,以满足某些Android需求,并且他们可能可以通过某些本地Linux文件系统来实现它。但是关键是我们需要一种FAT-like permission-less filesystemAndroid早期版本,以确保向后兼容,并且符合Android外部存储概念的设计。我进行了修改以阐明我的观点。
Irfan Latif
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.