Android文件存储

来源:互联网 发布:directx12优化 编辑:程序博客网 时间:2024/06/05 05:16

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)来删除内部空间的文件。
  


  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
1 0
原创粉丝点击