Android文件存储

Android使用文件系统来读取和保存文件的, 相关的包请参照java.io包下面的文件。

1) 选择内部存储(Internal Storage)或者是外部存储(External Storage)

Android设备有两个存储区域:内部存储和外部存储空间, 顾名思义, 内部存储是跟随android系统的, 外部系统是可拆卸的设备例如SD card等。

对于很多Android设备, 即使没有前面所说的外部设备(如SD card), 系统同样提供在内部存储区域上提供了一块空间作为"外部存储"。因此即使

没有可拆卸的外设,仍然后两套存储空间可供选择。API对两种外部设备是同样适用的。 下面是两种存储空间的一些特性:

a. 内部设备(Internal Storage)

1. 内部设备是一直存在的,并且是一直有效。

2. 默认情况下,存储在内部设备上的文件只能被自己的app单独访问。

3. 当卸载app的时候,系统会移除所有的保存在内部设备上的app文件。

由以上特点可以看出, 内部设备适合保存那些只有自己的app访问的数据和文件。 比如登录后的用户信息, 数据库文件等私密信息。

b. 外部设备(External Storage)

1. 外部设备并不保证是一直存在且有效的。比如user可能挂载了外部设备然后移除了它。

2. 外部设备是"公共区域", 存储在外部设备上的文件无法控制其私密性,其他app可以读取操作它。

3. 当卸载app的时候,系统只会移除存储在getExternalFilesDir()文件夹下的文件,其他的文件不会主动移除。 也就是说,会产生垃圾数据。

对比内部设备, 可以看出外部设备适合存储那些不需要阅读权限的文件。

2) 获取读写权限。

为了读取外部设备,需要在manifest中添加读写权限:

<manifest ...>

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

...

</manifest>

值得注意的是, 现在所有的app均有能力读取外部设备,并不需要特殊的读权限。 但是在未来的Android版本中,会加入更多的限制。

因此在你的app中,同样需要添加读权限已防备未来更新版本带来的麻烦。

<manifest ...>

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

...

</manifest>

而读写内部设备不需要任何权限。 app拥有读写它的内部存储空间的权利。

3) 存储文件到内部设备

当需要存储文件到内部空间时,可以通过File类的两种方法来获取存储路径

getFilesDir()     会返回你的app的内部存储空间的路径

getCacheDir()     返回你的app的内部存储空间的缓存目录, 如果缓存文件不太需要的话,请及时清理已保证缓存目录的以保证缓存文件不会占用太大空间,

比如1M, 不然系统有可能在没有警告的情况下直接删除缓存目录下的文件。

如果要在背部设备上创建文件,可以使用如下代码:

File file = new File(context.getFilesDir(), filename);

相应的,可以使用openFileOutput() 来获取FileOutputStream , 然后通过它来写文件到内部设备。下面是例子:

String filename = "myfile";
  String string = "Hello world!";
  FileOutputStream outputStream;

  try {
    outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
    outputStream.write(string.getBytes());
    outputStream.close();
  } catch (Exception e) {
    e.printStackTrace();
  }
  

或者是,你同样可以使用createTempFile()来创建文件, 下面的例子是通过url获取文件名,然后保存在缓存目录下:

public File getTempFile(Context context, String url) {
    File file;
    try {
        String fileName = Uri.parse(url).getLastPathSegment();
        file = File.createTempFile(fileName, null, context.getCacheDir());
    catch (IOException e) {
        // Error while creating file
    }
    return file;
  }

内部设备的目录是以你的包名存储的, 从技术上来说, 如果你把文件保存成readble模式,其他的app可以读取此文件,当然它要知道

你的包名和你的文件名。其他的app不能浏览你的内部文件夹, 如果你没有把文件属性设置为readable或者writable。

只要你使用MODE_PRIVATE模式,其他的app就不能访问你的文件。

4) 外部存储空间

因为外部空间是可拆卸的,因此在访问它之前,必须确保其存在。 Android提供了响应的接口来判断外设是否可用。当外设的状态为MEDIA_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;
  }

前面也提到过,外设上的文件也有区别, 有的随着app的卸载会被系统同时删除,有些目下的文件不会同时被删除。

因此, 根据你的文件的类型,你可以选择将他们保存在不同的目录下:

共有文件:

这些文件可同时被其他的app使用,当卸载时,不希望被删除,比如下载的图片,或者使用app拍摄的照片等。

私有文件:

你的app的单独使用的文件,在卸载时,希望同时被删除,尽管这些文件能够被其他的app访问,但对用户已经没有价值。例如一些缓存数据。

当你保存共有文件时,可以使用getExternalStoragePublicDirectory()方法来获取外设的根目录,在此根目录上创建新的文件路径。

这个方法需要指定你需要存储的类型,比如图片或者音乐等。例如:

  public File getAlbumStorageDir(String albumName) {
    // Get the directory for the user's public pictures directory.
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
  }

当你需要存储私有文件时,可以通过getExternalFilesDir(), 同样可以指定需要的类型, 例子如下:

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;
  }

如果不需要指定类型,可以传递null到getExternalFilesDir()中,它返回的是您的应用程序的在外部存储的根目录。

记住两者之间的区别。

5) 查询剩余空间

如果你知道需要保存的文件的大小,你需要保证有足够的空间来存储这些文件。

可以通过getFreeSpace() 或者 getTotalSpace() 来获取文件的大小。

6) 删除文件:

可以通过File的delete()方法来删除文件。或者通过context.deteleFile(fileName)来删除内部空间的文件。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-25 08:54:16

Android文件存储的相关文章

Android文件存储的问题:ClassLoader和实现Parcelable接口后 详解及用途

可能小伙伴们读了我上一篇博客关于Android文件存储的的,在文件操作的时候大家有没有疑问呀,有就对了,可能在保存自定义对象的时候,如何序列化呀?ClassLoader到底是啥鬼呀?序列化后怎么读取出来呀?好吧,针对于上面的问题,我一个一个的说明吧! 今天主要是讲ClassLoader的用途, ClassLoader主要对类的请求提供服务,当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回这个类的class对象. 1.1 几个相关概念ClassLo

Android文件存储详细完整示例

MainActivity如下: package cc.cv; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import android.os.Bundl

android文件存储位置切换

最近有个需求,助手的google卫星地图和OpenCycleMap下载的离线地图数据,要能够在内置存储和外置存储空间之间切换,因为离线瓦片数据非常大,很多户外用户希望将这些文件存储在外置TF卡上,不占用内置存储空间,所以把最近研究的整理了下,分享给大家. 需要考虑和遇到的问题(主要是不同手机.不同系统的兼容性): 1.这样获取手机所有挂载的存储器?   Android是没有提供显式的接口的,首先肯定是要阅读系统设置应用“存储”部分的源码,看存储那里是通过什么方式获取的.最后找到StorageMa

android: 文件存储

数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑 关机的情况下,这些数据仍然不会丢失.保存在内存中的数据是处于瞬时状态的,而保存在 存储设备中的数据是处于持久状态的,持久化技术则是提供了一种机制可以让数据在瞬时状 态和持久状态之间进行转换. 持久化技术被广泛应用于各种程序设计的领域当中,而本书中要探讨的自然是 Android 中的数据持久化技术.Android 系统中主要提供了三种方式用于简单地实现数据持久化功能, 即文件存储.SharedPreference 存储以

程序员带你学习安卓开发系列-Android文件存储

这是程序员带你学习安卓开发系列教程.本文章致力于面向对象程序员可以快速学习开发安卓技术. 上篇文章:.Net程序员快速学习安卓开发-布局和点击事件的写法 主要讲解了布局和点击事件的写法. 上篇文章补充: 控件单位介绍: px 像素 dip或者dp 设备独立像素 sp 比例像素 控件的高度宽度一般用dip或者dp.字体用sp. Android 存储数据项目: 描述:实现QQ登录效果.如图: 输入帐号密码,并勾选记住帐号 ,点击登录时,保存帐号信息.下次登陆可以直接显示上次保存的QQ帐号. 前台界面

Android文件存储使用参考

可能遇到的问题 android系统自身自带有存储,另外也可以通过sd卡来扩充存储空间.前者好比pc中的硬盘,后者好移动硬盘. 前者空间较小,后者空间大,但后者不一定可用. 开发应用,处理本地数据存取时,可能会遇到这些问题: 需要判断sd卡是否可用: 占用过多机身内部存储,容易招致用户反感,优先将数据存放于sd卡; 应用数据存放路径,同其他应用应该保持一致,应用卸载时,清除数据: 标新立异在sd卡根目录建一个目录,招致用户反感 用户卸载应用后,残留目录或者数据在用户机器上,招致用户反感 数据安全性

android 文件存储对文件名大小写不敏感

1.开发中发现,当两个文件名只有大小写的区别,其他都一样的情况,android中会默认是同一个文件. 比如,你在同一个文件夹下有一个文件 aa.txt   重新创建一个文件命名为AA.txt  android系统会认为这俩是同一个文件,从而出现覆盖的问题. 经测试发现,windows.Mac osx 系统也是这样的. 2.项目中遇到的问题是.创建文档时防止文件重名导致的覆盖问题.使用 file.exist()方法来判断文件是否存在,经测试发现: 存储路径时sd卡时,该方法不区分大小写,但是路径在

Android文件存储往SD卡中写入文件路径出错问题求解。

============问题描述============   因为学习需要  看的老罗的视频  关于数据存储往SD卡写文件的那一部分  几乎完全照办的敲的代码   结果在pad上测试的时候和预想的有区别     本来应该存储到SD卡中的文件结果跑到pad自带内存中去了...   然后我尝试过把路径直接自己手动写  还是一样存到了自带内存中  这到底是为什么啊? 顺带吐槽一下万恶的导师  十一还要我们加班 求大神们指导呀~   国庆节玩的开学哟!!! ============解决方案1======

Android数据存储之Android 6.0运行时权限下文件存储的思考

前言: 在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以往直接sdcard根目录上直接新建了一个xxx/cache/目录来做文件存储就会不是那么容易控制了,所以有必要重新认识一下Android文件存储的相关知识了. 背景: 有关外置sdcard的读写权限 <uses-permission android:name="android.permissi