美文网首页Android开发Android知识Android技术知识
Android 数据存储(二)文件存储

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

作者: 朋永 | 来源:发表于2017-07-20 14:22 被阅读0次

    转载请注明出处: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()。如果用户卸载您的应用程序,这些文件将被自动删除。

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


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

    相关文章

      网友评论

        本文标题:Android 数据存储(二)文件存储

        本文链接:https://www.haomeiwen.com/subject/apndkxtx.html