网站首页 > java教程 正文
Android使用一个非常类似与其他平台上的基于磁盘的文件系统. 这节课讲述如何利用File APIs在Android文件系统中读写文件.
File 对象非常适合于流式顺序数据的读写. 如图片文件或是网络中交换的数据等.
本课程将会演示如何在app中执行基本的文件相关操作. 假定读者已对linux的文件系统及java.io中标准的I/O APIs有一定认识.
存储在内部还是外部
所有的Android设备均有两个文件存储区域:"internal" 与 "external". 这两个名称来自于早先的Android系统,当时大多设备都内置了不可变的内存(internal storage)及一个类似于SD card(external storage)这样的可卸载的存储部件。之后有一些设备将"internal" 与 "external" 都做成了不可卸载的内置存储,虽然如此,但是这一整块还是从逻辑上有被划分为"internal"与"external"的。只是现在不再以是否可卸载进行区分了。 下面列出了两者的区别:
Internal storage:
- 总是可用的
- 这里的文件默认只能被我们的app所访问。
- 当用户卸载app的时候,系统会把internal内该app相关的文件都清除干净。
Internal是我们在想确保不被用户与其他app所访问的最佳存储区域。
External storage:
- 并不总是可用的,因为用户有时会通过USB存储模式挂载外部存储器,当取下挂载的这部分后,就无法对其进行访问了。
- 是大家都可以访问的,因此保存在这里的文件可能被其他程序访问。
- 当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
External是在不需要严格的访问权限并且希望这些文件能够被其他app所共享, 或者是允许用户通过电脑访问时的最佳存储区域。
保存到Internal Storage
当保存文件到internal storage时,可以通过执行下面两个方法之一来获取合适的目录作为 FILE 的对象:
getFilesDir
返回一个File,代表了我们app的internal目录。
getCacheDir
返回一个File,代表了我们app的internal缓存目录。请确保这个目录下的文件能够在一旦不再需要的时候马上被删除,并对其大小进行合理限制,例如1MB 。系统的内部存储空间不够时,会自行选择删除缓存文件。
可以使用File 构造器在那些目录下创建一个新的文件,如下:
File file = new File(context.getFilesDir, filename);
同样,也可以执行openFileOutput 获取一个 FileOutputStream 用于写文件到internal目录。如下:
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;
}
文件保存的位置在/data/data/<package name>/files/
目录下.
从Internal Storage读取文件
通过FileInputStream openFileInput(String name)
方法获取输入流.
private String read(String dir) {
try {
FileInputStream fis = openFileInput(dir);
byte buffer = new byte[1024];
int read = 0;
StringBuilder sb = new StringBuilder("");
while ((read = fis.read(buffer)) != -1) {
sb.append(new String(buffer, 0, read));
}
fis.close;
return sb.toString;
} catch (Exception e) {
e.printStackTrace;
}
return "error occured reading the file.";
}
当Android系统调用Context的openFileInput, openFileOutput方法获得IO流后, 接下来的用法与Java中的IO流用法完全一样.
保存文件到External Storage
声明权限
为了写数据到external storage, 必须在你manifest文件中请求WRITE_EXTERNAL_STORAGE权限:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
对于internal storage,我们不需要声明任何权限,因为程序默认就有读写程序目录下的文件的权限。
检查可用性
因为external storage可能是不可用的,比如遇到SD卡被拔出等情况时。因此在访问之前应对其可用性进行检查。我们可以通过执行 getExternalStorageState来查询external storage的状态。若返回状态为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;
}
尽管external storage对于用户与其他app是可修改的,我们可能会保存下面两种类型的文件。
Public files
这些文件对与用户与其他app来说是public的,当用户卸载我们的app时,这些文件应该保留。例如,那些被我们的app拍摄的图片或者下载的文件。
Private files
这些文件完全被我们的app所私有,它们应该在app被卸载时删除。尽管由于存储在external storage,那些文件从技术上而言可以被用户与其他app所访问,但实际上那些文件对于其他app没有任何意义。因此,当用户卸载我们的app时,系统会删除其下的private目录。例如,那些被我们的app下载的缓存文件
想要将文件以public形式保存在external storage中,请使用getExternalStoragePublicDirectory方法来获取一个 File 对象,该对象表示存储在external storage的目录。这个方法会需要带有一个特定的参数来指定这些public的文件类型,以便于与其他public文件进行分类。参数类型包括DIRECTORY_MUSIC 或者 DIRECTORY_PICTURES. 如下:
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;
}
生成文件的位置: /mnt/sdcard/Pictures/xxx
想要将文件以private形式保存在external storage中,可以通过执行getExternalFilesDir 来获取相应的目录,并且传递一个指示文件类型的参数。每一个以这种方式创建的目录都会被添加到external storage封装我们app目录下的参数文件夹下(如下则是albumName)。这下面的文件会在用户卸载我们的app时被系统删除。如下示例:
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;
}
生成文件的位置: /mnt/sdcard/Android/data/com.yusuzhan.editor/files/Pictures/xxx
查询剩余空间
如果事先知道想要保存的文件大小,可以通过执行getFreeSpace
orgetTotalSpace
来判断是否有足够的空间来保存文件,从而避免发生IOException
。那些方法提供了当前可用的空间还有存储系统的总容量。
删除文件
在不需要使用某些文件的时候应删除它。删除文件最直接的方法是直接执行文件的delete方法。
如果文件是保存在internal storage,我们可以通过Context来访问并通过执行deleteFile进行删除.
myContext.deleteFile(fileName);
NOTE:当用户卸载我们的app时,android系统会删除以下文件:
- 所有保存到internal storage的文件。
- 所有使用getExternalFilesDir方式保存在external storage的文件。
猜你喜欢
- 2025-01-06 Java 中文件目录监听实现
- 2025-01-06 五年开发,你还记得Java基础代码中的文件I/O操作么?
- 2025-01-06 「Java进阶」I/O操作必备知识点:字节流读写实例讲解
- 2025-01-06 一篇文章学会Groovy对文件的操作
- 2025-01-06 干货:MAC上轻松搞定查看Java汇编代码
- 2025-01-06 详细介绍一下在Spring Boot中有几种读取配置文件的方式?
- 2025-01-06 【每日一学】文件操作终极指南:Java开发者不可错过的技能
- 2025-01-06 【分享】教你如何使用 Java 读取 Excel、docx、pdf 和 txt 文件
你 发表评论:
欢迎- 04-24Java Collections 工具类集合框架中常用算法解析
- 04-24桶排序的简单理解
- 04-24Java集合框架底层实现原理大揭秘
- 04-24Java 集合框架全面解析:选对数据结构,提升开发效率
- 04-24c#集合排序
- 04-24Java面试中常被问到的集合类深度解读
- 04-24VBA技术资料MF278:对集合进行排序
- 04-24Spring 最常用的 7 大类注解,史上最强整理
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)