Android数据存储-文件存储-内部存储
所有的Android设备都有两个文件存储区域:内部存储和外部存储。内部存储都是指手机内部(这并不是说外部存储就是指的手机的外部SD卡之类的,外部存储物理上来说也有可能是在手机内部)。
内部存储中的文件只有您的应用本身可以访问,当用户卸载应用后,系统会从内部存储中移除您的应用中的所有文件。使用内部存储不需要申请权限。
使用场景
内部存储主要用来保存一些私有数据,如果你希望保存的数据只能被你自己的应用访问,那么内部存储是最佳的选择。
如何使用
保存长期数据
(保存在data/data/packagename/files)
(1)写入数据
既然要向内部存储中写入数据,那么我们需要得到指向内部存储文件的输出流,有两种方式获得:
1.调用Context对象的openFileOutput()获取写入到内部目录文件的FileOutputStream。
FileOutputStream fileOutputStream =context.openFileOutput("fileName",Context.MODE_PRIVATE);
2.使用File构造函数,指定内部存储的目录,通过File对象创建写入到内部目录文件的FileOutputStream。
File file = new File(context.getFilesDir(),"fileName");
FileOutputStream fileOutputStream = new FileOutputStream(file);
这两种方式都可能会抛出FileNotFoundException,如果你要写入的文件不存在就会抛出异常。
下面是一段从流中读取数据写入到内部存储文件的一段代码示例:
/*** 以文件的方式将数据写入到应用内部存储,不需要申请权限;* 文件是私有的,一般情况下只有你自己的应用可以访问此文件(通过FileProvider也可以实现共享);* 当用户卸载应用时,这些文件将随应用一起被移除。** @param context* @param fileName* @param inputStream* @param writeMode 写入方式,支持两种方式:* Context.MODE_PRIVATE;私有覆盖型* Context.MODE_APPEND;私有追加型*/public static void saveDataFileInternal(Context context, String fileName, InputStream inputStream, int writeMode) throws Exception {FileOutputStream fileOutputStream = null;try {fileOutputStream = context.openFileOutput(fileName, writeMode);byte[] writeBytes = new byte[DEFAULT_BUFFER_SIZE];int total = 0;while (-1 != (total = inputStream.read(writeBytes))) {fileOutputStream.write(writeBytes, 0, total);}} catch (Exception e) {Log.e(TAG,e.getMessage());throw new Exception("保存内部文件失败,要保存的文件:"+fileName);;} finally {try {if (fileOutputStream != null)fileOutputStream.close();} catch (IOException e) {e.printStackTrace();}}}
这段示例代码有两个细节点需要说明(如果你只是想要了解内部存储相关的知识点,这里可以忽略):
1.当我们将流中的数据写入文件时,不能将流中的数据全部加载到内存中再写入文件中,需要一部分一部分加载,否则一旦流中的数据过多时就会导致内存溢出(out of memory)。
2.对于异常这里的处理是捕获了系统异常(何为“系统异常”:我这里想说的是JDK或者Android SDK抛出的异常),然后抛出这个业务方法的异常。简单的来说就是将系统的异常隐藏,抛出用户想要知道的业务异常(因为对方法的调用者来说,它不需要知道究竟是什么系统异常,它只想知道这个业务有没有执行成功,如果错了,错在哪里)。
p.s. 对于这里的第2个细节点,很多是一些个人的观点,可能会有一些错误。
(2)读取数据
同样,读取数据也需要获得指向内部存储文件的输入流,与写入数据的不同之处只是需要调用Context对象的openFileInput()方法,而不是openFileOutput()方法。
下面是一段从内部存储中读取文件数据返回文本字符串的代码示例:
/*** 读取内部存储中的文件** @param context* @param fileName* @return*/public static String readDataFileInternal(Context context, String fileName) throws Exception {StringBuilder readContent = new StringBuilder();InputStream inputStream = null;try {inputStream = context.openFileInput(fileName);InputStreamReader inputStreamReader = new InputStreamReader(inputStream, CHARSET_UTF8);char[] readChar = new char[DEFAULT_BUFFER_SIZE];int total = 0;while (-1 != (total = inputStreamReader.read(readChar))) {readContent.append(readChar, 0, total);}} catch (Exception e) {Log.e(TAG,e.getMessage());throw new Exception("读取内部文件失败,要读取的文件:"+fileName);} finally {try {if (inputStream != null) {inputStream.close();}} catch (IOException e) {e.printStackTrace();}}return readContent.toString();}
缓存数据
(保存在data/data/packagename/cache)
缓存数据是指你不想要永久存储在内部的数据,写入/读取缓存数据的方式和保存长期内部数据的方式基本一致,只是在获取输入/输出流上略有不同。
获取输出流:
File file = new File(context.getCacheDir(),"fileName");
FileOutputStream fileOutputStream = new FileOutputStream(file);
获取输入流:
File file=new File(context.getCacheDir(),fileName);
FileInputStream fileInputStream = new FileInputStream(file);
需要注意的是:
1.缓存的数据量不要太大,需要保持在合理的限制范围内(例如1MB,这个数据是Android官网给的)。
2.需要始终自行维护缓存文件,当缓存文件不再需要时,及时进行删除。
3.当手机存储即将耗尽时,系统会在不进行警告的情况下删除你的缓存文件。当你的应用被卸载时,这些缓存文件也会被移除。
一些补充
(1)内部文件的存储模式:
Context.MODE_PRIVATE;——应用私有文件
Context.MODE_APPEND;——数据追加型(保留原文件的数据,向文件中写入新数据)
Context.MODE_WORLD_READABLE;——其它应用可读
Context.MODE_WORLD_WRITEABLE;——其它应用可写
其中
Context.MODE_WORLD_READABLE;——其它应用可读
Context.MODE_WORLD_WRITEABLE;——其它应用可写
从API17(Android4.2)之后已经被弃用(deprecated),Android N(7.0)以后如果再使用就会抛出一个SecurityException。
(2)共享私有文件
如果你的应用想要与其它应用共享私有文件,则可以将FileProvider与FLAG_GRANT_READ_URI_PERMISSION配合使用。
如果你想尝试共享“file://URI”,从Android N(7.0)以后将会引发FileUriExposedException。无论你是不是运行在7.0以上,都建议不要再使用这种方式。
(3)删除文件
当你的应用的某些文件已经确定不再需要时,你应该主动删除它。
1.你可以调用File的delete()方法来删除文件:
file.delete()
2.如果你的文件保存在内部存储空间中,你可以通过请求Context来调用deleteFile来删除文件:
context.deleteFile("fileName");
有时候我们总是在不停的写入数据文件,而总是忘记去维护这些文件,这样会导致手机的存储在不断变少,Android官方建议应用应该定期删除不再需要的文件。
参考:
https://developer.android.google.cn/training/basics/data-storage/files.html
https://developer.android.google.cn/guide/topics/data/data-storage.html
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
