/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
то , что от владельца устройства
* VIEW
является одним из read
(для приложений с permission.READ_EXTERNAL_STORAGE) или write
(permission.WRITE_EXTERNAL_STORAGE) или default
(для процессов , запущенных в корне / global namespace т.е. т.е. вне zygote)
* В предыдущих версиях Android были незначительные различия, но концепция эмуляции с тех пор была реализована.
* Для получения более подробной информации о реализации пространства имен монтирования Android см. Этот ответ .
Короче говоря, /sdcard
и /storage/emulated/0
- которые представляют файловую систему FAT / vFAT / FAT32 - указывают на /data/media/0
(или /mnt/expand/[UUID]/media/0
в случае приемлемого хранения ) сквозной FUSE
или sdcardfs
эмуляции.
Будучи не специфичным для Android, но в основном связанным с Linux, symlink и bind mount (см. «Создание bind mount») выходят за рамки этого вопроса, поскольку речь идет в основном о части эмуляции.
Эмуляция:
Почему эмуляция здесь? Эмулируемая файловая система - это уровень абстракции в реальной файловой системе ( ext4
или f2fs
), который служит в основном двум целям:
- Сохранение USB-подключения устройств Android к ПК (теперь через MTP осуществляется через несколько дней)
- Ограничить несанкционированный доступ приложений / процессов к личным носителям пользователя и данным других приложений на SD-карте.
Прочитайте Android Storage Storage Путешествие для деталей, резюме:
В ранних устройствах Android не хватало внутренней памяти и использовались (физически) внешние SD-карты, которые традиционно используют файловую систему семейства FAT для обеспечения совместимости с большинством ПК (см. Доминирование Microsoft в мире ПК).
Когда размер внутреннего хранилища вырос, та же файловая система была переведена на внутреннюю (все еще называемую «внешнюю») SD-карту.
Но реализация FAT / vFAT имела две основные проблемы, которые Google постепенно решала:
- Устройства Android были подключены к ПК напрямую ( USB Mass Storage ) так же, как мы подключаем USB-накопитель в наши дни. UMS предоставляет устройство на уровне блоков и отключает SD-карту от платформы Android (отключает монтирование), что делает целые данные недоступными для приложений и, возможно, нарушает многие функции.
- FAT (любимый в Windows в дни разработки) никогда не был предназначен для обеспечения разрешений UNIX ( символические ссылки mode, uid, gid и аналогичные , и тому
ioctls
подобное FS_IOC_FIEMAP
). Таким образом, все данные на SD-карте были доступны всем приложениям (поскольку каждое приложение Android является пользователем UNIX / Linux и имеет идентификатор пользователя) без ограничений, что вызывает серьезные проблемы с безопасностью и конфиденциальностью.
Обе эти проблемы были решены с помощью эмуляции:
- Фактическое хранилище SD-карты было перемещено в
/data
раздел (или независимый раздел / sdcard на некоторых устройствах ранее), который содержит ext4
файловую систему (постепенно заменяющуюся f2fs
), полностью реализуя разрешения UNIX.
- Этот дизайн сделал использование UMS невозможным, поскольку весь
/data
раздел не мог быть открыт для ПК по двум причинам: (1)
он содержит множество настроек и данных приложений, которые должны быть защищены от других приложений, а также от пользователей. (2)
Файловые системы Linux не поддерживаются Windows.
Таким образом, UMS был заменен на Media Transfer Protocol, который является расширением типа клиент-сервер для PTP - уже установленный протокол. MTP не предоставляет блочное устройство, но работает через программный стек. Хост MTP работает на Android как приложение ( android.process.media
), полностью изолированное в среде 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 и предоставьте разрешение на хранение . Выполните команды еще раз:
Смотрите разницу в разрешениях для одинаковых файлов и каталогов. Кажется, что это просто невозможно без эмуляции в собственной файловой системе 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
Также см. Что такое UID «u # _everybody»?
Связанный: