内部存数和外部存储

本文详细介绍了Android应用中的内部存储和外部存储机制,包括不同类型的存储特点、如何获取存储权限、保存和删除文件的方法以及如何检查存储空间等关键信息。

内部存数和外部存储


本文是参照Android文档进行的一些总结,内容和文档的内容基本一样,旨在加深自己的记忆.

内部存储

  • 它始终可用

  • 只有您的应用可以访问此处保存的文件

  • 当用户卸载应用时,系统会从内部存储中移除应用的所有文件

注意:当希望用户或外部应用无法访问你的文件,内部存储是最佳选择,非root用户

外部存储

  • 它是全局的,因此此处保存的文件可能不受您控制的被读取

  • 当用户卸载你的应用时,只有在你通过getExteranlFileDir()将你的应用文件保存在目录中时,系统才会从此处移除你的应用文件

  • 对于无需访问限制以及你希望与其他应用共享或允许用户使用计算机访问的文件,外部存储是最佳位置.

提示: 尽管应用默认安装在内部存储中,但你可以在清单配置文件中指定 android:installLocation 属性,这样你的应用便可以安装在外部存储中,当APK非常大且它们的外部存储空间大于内部存储空间时,用户更青睐这个选择.

获取外部存储权限

要向外部存储写入信息,需要在manifest.xml文件中请求WRITE_EXTERNAL_STORAGE权限.

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

注意: 目前,所有的应用都可以读取外部存储,而且无需特别权限.如果应用只需要读取外部存储权限,但不向其写入信息,可以将权限声明为READ_EXTERNAL_STORAGE.

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

但是如果应用使用WRITE_EXTERNAL_STORAGE权限,那么它隐含读取外部存储的权限.

将文件保存在内部存储

在内部存储中保存文件时,可以通过调用以下两种方式之一获取作为File的目录.

  • getFilesDir(): 返回表示您的应用的内部目录的file.
    /data/data/应用程序包名/files/

  • getCacheDir(): 返回表示您的应用临时缓存文件内部目录的File.务必删除所有不再需要的文件并对在指定时间您使用的内存量实现合理大小限制.
    /data/data/应用程序包名/cache/

要在这些文件中新建文件,可以使用File()构造函数,传递指定内部存储目录(files或者cache).

向内部存储的files文件写入文件

// 创建一个空的文件
File file = new File(getFilesDir(), "dyl_myFile--1");
try {
    file.createNewFile();
} catch (IOException e) {
    e.printStackTrace();
}


// openFileOutput:Context的一个抽象方法,打开一个和当前应用相关的私有文件用来写入.    
// 向内部存储写入一个字符串,文件名字为dyl_myFile
String string = "Hello world!";
FileOutputStream outputStream;
try {
    outputStream = openFileOutput("dyl_myFile", Context.MODE_PRIVATE);
    outputStream.write(string.getBytes());
    outputStream.close();
} catch (Exception e) {
    e.printStackTrace();
}

如果需要缓存某些文件,应该使用createTempFile().

// prefix:文件的名字
// suffix:文件的后缀,不填默认为.tmp
// directory:要创建的目录文件,为空使用默认目录
File createTempFile (String prefix, String suffix,File directory)

注意: 你的应用的内部存储设备目录由你的应用在Android文件系统特定位置中的软件包名称指定.从技术上讲,如果你将文件模式设置为可读,那么,另一个应用也可以读取你的内部文件.但是,此应用也需要知道你的应用的软件包名称和文件名.其他应用无法浏览你的内部目录并且没有读写权限,除非你明确将文件设置为可读可写.只要将内部存储上的文件使用MODE_PRIVATE,其他应用便从不会访问它.

将文件保存在外部存储

外部存储可能不可用,比如:当用户已将存储装载到电脑或已移除提供外部存储的SD卡时,在使用它时,应始终确认它的容量,可以通过调用 getExternalStorageState()查询外部存储存储状态.如果返回状态是MODE_MOUNTED,那么你可以对文件进行读写.检测外部存储是否刻度可写.

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

尽管外部存储可被用户和其他应用进行修改,但是在此处保存两类文件:
- 公共文件
供其它应用和用户自由使用的文件,当用户卸载您的应用时,用户仍可以使用这些文件.
例如:应用拍摄的照片或已下载的文件
- 私有文件
属于你的应用且在用户卸载你的应用时应予删除的文件.尽管这些文件在技术上可被用户和其他应用访问(因为它们在外部存储中),但它们实际上不向您的应用之外的用户提供任何输出值.当用户卸载你的应用时,系统会删除应用外部私有目录中的所有文件.

如果要将公共文件保存在外部存储上,可以使用getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) 获取表示外部存储设备上的相应目录的File.

// 目录结构:/storage/emulated/0/Pictures
// public static String DIRECTORY_MUSIC = "Music";
// public static String DIRECTORY_PODCASTS = "Podcasts";
// public static String DIRECTORY_RINGTONES = "Ringtones";
// public static String DIRECTORY_ALARMS = "Alarms";
// public static String DIRECTORY_NOTIFICATIONS = "Notifications";
// public static String DIRECTORY_PICTURES = "Pictures";
// public static String DIRECTORY_MOVIES = "Movies";
// public static String DIRECTORY_DOWNLOADS = "Download";
// public static String DIRECTORY_DCIM = "DCIM";
// public static String DIRECTORY_DOCUMENTS = "Documents";

public File getAlbumStorageDir(String albumName) {

    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

保存应用的专有文件,调用 Context.getExternalFilesDir() 并向其指示想要的目录类型名称获取相应的目录.通过这种方法创建的各个目录将添加至封装你应用的所有外部存储设备文件的父目录,当应用卸载时,系统会删除这些文件.

// 目录结构:/storage/emulated/0/Android/data/luxshare_ict.dyl_test/cache
public File getAlbumStorageDir(Context context, String albumName) {
    // Get the directory for the app's private pictures directory.
    File file = new File(context.getExternalFilesDir(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

查询可用空间

  • getFreeSpace(): 获取文件可用控件,通过File对象来调用该方法
  • getTotalSpace: 获取存储总空间,通过File对象调用

注意: 在不知道文件大小的情况下,保存文件之前,可以不用检查可用空间量就立即写入文件,然后在IOException出现时将其捕获.

删除文件

删除不再需要的文件,调用delete方法即可. 如果删除的File是文件夹,则文件夹必须是空的才可以被删除

myFile.delete();

如果文件保存在内部存储,可以通过context的deleteFile()来定位和删除. ==这个方法只能删除

// fileName 要删除的文件名
myContext.deleteFile(fileName);

// 删除 /data/data/应用程序包名/files/dyl_myFile--1文件
File file = new File(getFilesDir(), "dyl_myFile--1");
deleteFile(file.getName())

注意: 当用户卸载应用时,Android会删除以下内容:
- 保存在内部存储中的所有文件

  • getExternalFilesDir()保存在外部存储中的所有文件. getExternalFilesDir() 对应的目录:/storage/emulated/0/Android/data/应用程序包名/files

应该手动删除getCacheDir()定期创建的所有缓存并且定期删除不在需要的其他文件.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值