美文网首页
Android文件系统

Android文件系统

作者: 狂奔的_土豆 | 来源:发表于2020-05-18 15:29 被阅读0次

    内部存储

    内部存储主要用于保存应用的私有文件,其他应用无法访问这些数据。当应用卸载的时候,这些数据也会被删除。使用内部存储不需要任何额外权限。

    1.写入数据

    FileOutputStream outputStream = context.openFileOutput("filePath", Context.MODE_PRIVATE);
    

    2.读取数据

    FileInputStream inputStream = context.openFileInput("filePath");
    

    3.读取读取静态文件

    InputStream inputStream = context.getResources().openRawResource(R.raw.rawfile) ;
    

    注意,在raw文件夹中,文件名只能包含小写字母、数字和下划线。

    4.缓存数据

    File cacheFile = context.getCacheDir();
    

    这个File对象对应的就是内部存储中用于保存缓存数据的根目录。
    注意,应用的私有缓存文件不应该过大。如果内部存储空间不足,系统可能会删除这些缓存文件。为了保证良好的用户体验,应用应该定期主动清除自己的缓存数据。

    外部存储

    除了内部存储,Android系统还为开发者提供了外部存储。外部存储并不仅仅指SD卡,它可能是可移除的存储介质(典型如SD卡),也可能是不可移除的存储介质(如现在很多一体机内置的存储器)。外部存储是相对于内部存储的概念,用于保存全局范围可读取的文件。这也就意味着,保存在外部存储中的数据可以被设备中的任何应用访问,甚至也可以被用户查看、修改。

    1.申请权限

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

    如果应用同时有读、写的需求,只需要申请WRITE_EXTERNAL_STORAGE权限即可。
    注意,Android 6.0(API 23、Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)引入了运行时权限的概念,以上提到的两种权限都需要动态地获取。

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
            android:maxSdkVersion="18"/>
    

    在Android 4.4(API 19)及以上,如果只是在外部存储中读、写应用的私有文件,就不需要申请这些权限。因此,我们可以使用maxSdkVersion属性实现只在较低版本申请权限,如上所示。

    2.Environment中定义的外部存储状态常量:

    MEDIA_UNKNOWN:未知状态
    MEDIA_REMOVED:移除状态(外部存储不存在)
    MEDIA_UNMOUNTED:未装载状态(外部存储存在但是没有装载)
    MEDIA_CHECKING:磁盘检测状态
    MEDIA_NOFS:外部存储存在,但是磁盘为空或使用了不支持的文件系统
    MEDIA_MOUNTED:就绪状态(可读、可写)
    MEDIA_MOUNTED_READ_ONLY:只读状态
    MEDIA_SHARED:共享状态(外部存储存在且正通过USB共享数据)
    MEDIA_BAD_REMOVAL:异常移除状态(外部存储还没有正确卸载就被移除了)
    MEDIA_UNMOUNTABLE:不可装载状态(外部存储存在但是无法被装载,一般是磁盘的文件系统损坏造成的)
    

    3.外部存储可写、可读

    public boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            return true;
        }
        return false;
    }
    

    4.外部存储至少可读

    public boolean isExternalStorageReadable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state) ||
            Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            return true;
        }
        return false;
    }
    

    公共文件(共享文件)

    对于在应用中产生的多媒体类型的文件,如音乐、图片、铃声等,一般应该保存在外置存储中对应的公共目录下,如/Music、/Pictures、/Ringtones,这样方便和其他的应用共享这些文件。同时,系统的媒体扫描器也能正确地对这些文件进行归类。

    1.Environment中定义文件类型的常量:

    DIRECTORY_MUSIC:音乐类型
    DIRECTORY_PICTURES:图片类型
    DIRECTORY_MOVIES:电影类型
    DIRECTORY_DCIM:照片类型
    DIRECTORY_DOWNLOADS:下载文件类型
    DIRECTORY_DOCUMENTS:文档类型
    DIRECTORY_RINGTONES:铃声类型
    DIRECTORY_ALARMS:闹钟提示音类型
    DIRECTORY_NOTIFICATIONS:通知提示音类型
    DIRECTORY_PODCASTS:播客音频类型
    

    2.获取共享文件目录

    File file = Environment.getExternalStoragePublicDirectory(String type);
    

    注意,返回的文件目录可能还不存在,因此在执行文件操作前应该确保相应的文件目录已经存在,否则使用File的mkdirs方法创建文件目录。

    小技巧:如果不希望系统的媒体扫描器访问我们的媒体文件,可以在媒体文件所在的目录下新建一个名为.nomedia的空文件,这会阻止媒体扫描器归类我们的文件并提供给其他应用。

    私有文件

    对于应用私有的文件,则应该使用Context的getExternalFilesDir方法访问外部存储中的私有存储目录,媒体扫描器不会扫描这些目录。可以为这个方法传入一个String类型的type参数,用于获取私有存储目录中相应的媒体文件子目录。当然,也可以传入null直接获取私有存储的根目录。这个方法的返回值也是一个File对象。

    1.Environment中定义文件类型的常量:

    DIRECTORY_MUSIC:音乐类型
    DIRECTORY_PICTURES:图片类型
    DIRECTORY_MOVIES:电影类型
    DIRECTORY_RINGTONES:铃声类型
    DIRECTORY_ALARMS:闹钟提示音类型
    DIRECTORY_NOTIFICATIONS:通知提示音类型
    DIRECTORY_PODCASTS:播客音频类型
    

    另外,出于兼容性的考虑,可以使用ContextCompat的getExternalFilesDirs方法。这是一个静态方法,返回值也是一个File数组。在Android 4.4及以上,效果和Context的getExternalFilesDirs方法一致;而在Android 4.3及以下,返回的File数组始终只包含一个对象。

    注意,某些移动设备可能既提供了内置存储器作为外部存储空间,同时又提供了SD卡作为外部存储空间。也就是说,在这些设备中外部存储实际上包含了两块磁盘。在Android 4.3(API 18)及以下,Context的getExternalFilesDir方法仅仅会返回内置存储器对应的外部存储控件,而无法访问SD卡对应的存储空间。从Android 4.4(API 19)开始,Context新增了getExternalFilesDirs方法。这个方法的返回值是一个File数组,包含两个对象(可能为null),这样就可以实现对内置存储器和SD卡的访问。数组的第一个对象默认是外部主存储,官方的开发建议是除非这个位置已满或不可用,否则应该使用这个位置。

    注意,当应用卸载时,这些私有存储目录中的文件也会被删除。此外,虽然系统的媒体扫描器不会访问外部存储中的私有存储目录,但是其他具有READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE权限的应用依旧可以读/写这些私有存储目录中的文件。因此对于真正重要的文件,还是应该保存在应用的内部存储中。
    补充:私有文件根目录的参考路径:Android/data/包名/files/

    缓存文件

    在外部存储中也有专门保存缓存文件的空间,可以通过Context的getExternalCacheDir方法访问缓存文件目录,返回值是一个File对象。上文曾说过,外部存储可能同时包含内置存储器和SD卡两个存储空间,因此在Android 4.4(API 19)及以上还可以通过Context的getExternalCacheDirs方法访问这两个存储空间。这个方法会返回一个File数组,包含两个对象,第一个对象默认是外部主存储对应的缓存文件目录。

    同样,为了兼容性,也可以使用ContextCompat的getExternalCacheDirs方法。这是一个静态方法,返回值也是一个File数组。在Android 4.4及以上,效果和Context的getExternalCacheDirs方法一致;而在Android 4.3及以下,返回的File数组始终只包含一个对象。
    注意,当应用卸载时,缓存目录下的文件也会被系统删除。当然,官方建议开发者应该主动移除不再需要的缓存文件,这有助于节省存储空间并保持应用性能。
    补充:缓存文件根目录的参考路径:Android/data/包名/cache/

    相关文章

      网友评论

          本文标题:Android文件系统

          本文链接:https://www.haomeiwen.com/subject/rrruohtx.html