Android 数据存储(二)文件存储

转载请注明出处:http://www.jianshu.com/p/21b266d6b6d7

之前说了下Android中Sharedpreferences、SQLite Databases的使用,不太会这两个的可以参考这两篇文章:
[Android 数据存储 (一)SharedPreferences]、
[Android 数据存储 (三)SQLite Databases]。
这篇主要说一下文件存储(内部存储和外部存储)。


1 Internal Storage

Internal Storage:内部存储器。
我们可以直接将文件保存在设备的内部存储设备上。默认情况下,保存到内部存储的文件对您的应用程序是私有的,其他应用程序无法访问它们(用户也不可以)。当用户卸载您的应用程序时,这些文件将被删除。

创建和写入私有文件到内部存储

String content = "abcdefghigk";
try {
    FileOutputStream os = openFileOutput("internal.txt", MODE_PRIVATE);
    //写数据
    os.write(content.getBytes());
    os.close();//关闭文件
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
  1. 调用openFileOutput(),参数:文件的名称和操作模式。这返回一个FileOutputStream。该方式创建的文件路径为:/data/data/<包名>/files/目录下。
  2. write()将字符串写入文件。
  3. close()关闭输出流。

文件操作模式有以下四种:

  • MODE_PRIVATE 将创建文件(或替换相同名称的文件),并使其对您的应用程序是私有的。
  • MODE_APPEND 如果文件已经存在,则将数据写入现有文件的末尾,而不是将其删除。
  • MODE_WORLD_READABLE 可读(不建议)
  • MODE_WORLD_WRITEABLE 可写(不建议)

从内部存储读取文件

byte buffer[] = new byte[4096];
try {
    FileInputStream in = openFileInput("internal.txt");
    //将数据读到buffer.
    int len = in.read(buffer);
    in.close();//关闭文件
    Log.i(TAG, "buffer="+new String(buffer,0,len));
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
  1. 调用openFileInput()并传递要读取的文件的名称。这返回一个FileInputStream。
  2. 从文件中读取字节read()。
  3. 然后关闭流 close()。

如果要在编译时保存应用程序中的静态文件,请将该文件保存在项目res/raw/目录中。您可以打开它 openRawResource(),传递资源ID(R.raw.<filename>)。此方法返回一个 可用于读取文件(但不能写入原始文件)的 InputStream实例。

保存缓存文件

如果您想缓存一些数据,而不是持久存储,那么您应该使用它getCacheDir()来打开File代表应用程序应该保存临时缓存文件的内部目录。

当设备的内部存储空间不足时,Android可能会删除这些缓存文件以恢复空间。但是,您不应该依靠系统来清理这些文件。您应该始终自己维护缓存文件,并保持在合理的空间上限,例如1MB。当用户卸载您的应用程序时,这些文件将被删除。

其他有用的方法

  • getFilesDir()
    获取保存内部文件的文件系统目录的绝对路径。
  • getDir()
    在内部存储空间内创建(或打开现有的)目录。
  • deleteFile()
    删除保存在内部存储上的文件。
  • fileList()
    返回应用程序当前保存的文件数组。

2 External Storage

每个Android兼容设备都支持一个共享的“外部存储”,您可以使用它来保存文件。这可以是可移动存储介质(例如SD卡)或内部(不可移动)存储。保存到外部存储器的文件是可读的,用户可以在使用USB大容量存储在计算机上传输文件时进行修改。

注意:如果用户将外部存储器安装在计算机上或删除了介质,则外部存储可能会变得不可用,并且您保存到外部存储器的文件没有执行安全性。所有应用程序都可以读取和写入放在外部存储上的文件,用户可以将其删除。

访问外部存储

为了在外部存储上读取或写入文件,您的应用程序必须获取 <font color =blue>READ_EXTERNAL_STORAGE </font><font color =blue>WRITE_EXTERNAL_STORAGE</font>系统权限。例如:

<uses-permission android:name = “android.permission.READ_EXTERNAL_STORAGE” />
<uses-permission android:name = “android.permission.WRITE_EXTERNAL_STORAGE” />

如果您需要读取和写入文件,则需要仅请求 WRITE_EXTERNAL_STORAGE权限,因为它隐含地还需要读取访问权限。

注意:从Android 4.4开始,如果您正在阅读或仅写入您的应用程序的私有文件,则不需要这些权限。

检查媒体可用性

在对外部存储进行任何处理之前,应始终调用getExternalStorageState()以检查介质是否可用。介质可能安装到计算机,丢失,只读或处于某种其他状态。这里有几种可用于检查可用性的方法:

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

该getExternalStorageState()方法返回您可能想要检查的其他状态,如媒体是否被共享(连接到计算机),完全丢失,已被删除等等。您可以使用这些来通知用户更多信息您的应用程序需要访问媒体。
保存可与其他应用共享的文件

从媒体扫描器隐藏您的文件

通常,用户可以通过应用程序获取的新文件应该保存到其他应用可以访问的设备上的“公共”位置,用户可以轻松地从设备中复制它们。这样做时,你应该使用的共享的公共目录,如之一Music/,Pictures/和Ringtones/。

为了得到一个File较合适的公共目录,呼叫getExternalStoragePublicDirectory(),通过它你想要的目录的类型,如 DIRECTORY_MUSIC,DIRECTORY_PICTURES, DIRECTORY_RINGTONES,或其他。通过将文件保存到相应的媒体类型目录,系统的媒体扫描器可以对系统中的文件进行适当的分类(例如,铃声在系统设置中显示为铃声,而不是音乐)。

例如,以下是在公共图片目录中为新相册创建目录的方法:

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()。此方法还需要一个type参数来指定子目录的类型(如DIRECTORY_MOVIES)。如果您不需要特定的媒体目录,请传递null以接收您应用的私有目录的根目录。

从Android 4.4开始,在应用程序的私有目录中读取或写入文件不需要READ_EXTERNAL_STORAGE 或WRITE_EXTERNAL_STORAGE 权限。因此,您可以通过添加maxSdkVersion 属性来声明只能在较低版本的Android上请求权限:

<uses-permission android:name = “android.permission.WRITE_EXTERNAL_STORAGE” android:maxSdkVersion = “18” />

注意: 当用户卸载您的应用程序时,此目录及其所有内容将被删除。此外,系统介质扫描程序不会读取这些目录中的文件,因此它们无法从MediaStore内容提供程序访问。因此,您不应将这些目录用于最终属于用户的媒体,例如您的应用程序捕获或编辑的照片,或用户使用您的应用购买的音乐 - 这些文件应保存在公共目录中。

保存缓存文件

打开一个File,该File代表您应该保存缓存文件的外部存储目录,请调用getExternalCacheDir()。如果用户卸载您的应用程序,这些文件将被自动删除。

提示: 要保留文件空间并保持应用程序的性能,请务必仔细管理缓存文件,并在整个应用程序的生命周期中删除不再需要的缓存文件。


欢迎大家关注、评论、点赞
你们的支持是我坚持的动力。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容