zoukankan      html  css  js  c++  java
  • android基础---->数据保存到文件

      Android使用与其他平台类似的基于磁盘的文件系统(disk-based file systems)。这篇博客将描述如何在Android文件系统上使用File的读写APIs对Andorid的file system进行读写。File 对象非常适合于流式顺序数据的读写,如图片文件或是网络中交换的数据等。

    目录导航

    1. 文件的存储位置Internal 和External 
    2. 文件保存到Internal Storage
    3. 文件保存到External Storage
    4. 文件的常用位置总结
    5. 友情链接

    文件的存储位置

    Internal storage: 

    • 总是可用的
    • 这里的文件默认只能被我们的app所访问。
    • 当用户卸载app的时候,系统会把internal内该app相关的文件都清除干净。
    • Internal是我们在想确保不被用户与其他app所访问的最佳存储区域。

    External storage:

    • 并不总是可用的,因为用户有时会通过USB存储模式挂载外部存储器,当取下挂载的这部分后,就无法对其进行访问了。
    • 是大家都可以访问的,因此保存在这里的文件可能被其他程序访问。
    • 当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
    • External是在不需要严格的访问权限并且希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。

    APP安装的位置:

    • app是默认被安装到internal storage的,我们还是可以通过在程序的manifest文件中声明android:installLocation属性来指定程序安装到external storage。
    • 当某个程序的安装文件很大且用户的external storage空间大于internal storage时,用户会倾向于将该程序安装到external storage。
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal"
        package="com.example.linux.filesavetest">

    保存到Internal Storage

    一、 当保存文件到internal storage时,可以通过执行下面两个方法之一来获取合适的目录作为 FILE 的对象:

    • getFilesDir() :  返回一个File,代表了我们app的internal目录。
    • getCacheDir() : 返回一个File,代表了我们app的internal缓存目录。系统的内部存储空间不够时,会自行选择删除缓存文件。

    二、 好了,现在我们通过一个实例来了解下文件在Internal Storage中的存储与读取:

    • 在Internal中写入内容到文件,创建文件: File file = new File(context.getFilesDir(), filename);
    // 在Internal中存储文件
    public void saveInternal(View view) {
        String fileContent = "最难受的思念,不是对方不知道你的思念,而是他知道却无所谓。有些人,无论你怎么对他好,他也不会留意,因为他的生命里,你显得是多么的微不足道.";
        FileOutputStream outputStream;
    
        try {
            outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
            outputStream.write(fileContent.getBytes("utf-8"));
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    • 上述的openFileOutput方法,其实也是在app的Internal目录下创建文件:其中有这样的代码:
    File f = makeFilename(getFilesDir(), name);
    • 在Internal中读取文件中的内容:
    // 在Internal中读取文件
    public void getInternal(View view) {
        byte[] buffer = new byte[1024];
        FileInputStream fileInputStream;
    
        try {
            fileInputStream = openFileInput(filename);
            fileInputStream.read(buffer);
            fileInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        textView.setText(new String(buffer));
    }
    • 如果需要缓存一些文件,可以使用createTempFile(),以下方法创建了一个以user开头的后面加上一些随机数的tmp文件
    // 创建缓存文件
    public void createTempFile(View view) {
        File file = null;
        try {
            file = File.createTempFile("users", null, this.getCacheDir());
        } catch (IOException e) {
            e.printStackTrace();
        }
        Log.i(TAG, "temp file: " + file != null ? file.getAbsolutePath() : "no such file.");
    }
    • 日志结果:   /data/data/com.example.linux.filesavetest/cache/users1907557754.tmp

    三、 文件的几种模式:

    • MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
    • MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容
    • MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。
    • MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。

    四、 如果希望文件被其他应用读和写,可以设置mode: MODE_WORLD_READABLE + MODE_WORLD_WRITEABLE

    从技术上讲,如果文件被设置为可读的,那么其他app就可以读取该internal文件。然而,其他app需要知道包名与文件名。若没有设置为可读或者可写,其他app是没有办法读写的。因此我们只要使用了MODE_PRIVATE ,那么这些文件就不可能被其他app所访问。

    保存到External Storage

    一、 因为external storage可能是不可用的,比如遇到SD卡被拔出等情况时。因此在访问之前应对其可用性进行检查。我们可以通过执行 getExternalStorageState()来查询external storage的状态。若返回状态为MEDIA_MOUNTED, 则可以读写。

    public boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.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下载的缓存文件。

    三、 一些其它的说明

    • getExternalFilesDir() 方法会创建的目录会在app被卸载时被系统删除。如果我们的文件想在app被删除时仍然保留,请使用getExternalStoragePublicDirectory().
    • 查询剩余空间:可以通过执行getFreeSpace() or getTotalSpace() 来判断是否有足够的空间来保存文件,从而避免发生IOException
    • 删除文件: 执行文件的delete()方法;文件是保存在internal storage:myContext.deleteFile(fileName);
    • 通常来说,我们应该手动删除所有通过 getCacheDir() 方式创建的缓存文件,以及那些不会再用到的文件。

    四、 当用户卸载我们的app时,android系统会删除以下文件

    • 所有保存到internal storage的文件。
    • 所有使用getExternalFilesDir()方式保存在external storage的文件。

    文件的常用位置总结

    一、 内置私有目录:

    • /data/data/[packagename]/files:文件缓存目录,一般存小的文件缓存,如果是图片,不建议放这里,一般放到外置卡。File file = getFilesDir(); 

    • /data/data/[packagename]/cache:目录,存放一些其他缓存 File cache = getCacheDir();

    • /data/data/[packagename]/databases,存放数据库

    • /data/data/[packagename]/shared_prefs 应用的SharedPreferences保存
    • /data/data/[packagename]/lib,应用的so目录

    二、 外置SDCARD目录

    • 外置缓存目录(File sdcache = getExternalCacheDir();) /storage/emulated/0/Android/data/[packagename]/cache 一些重要性不高的cache或者大文件放到这里,比如图片缓存
    • 外置文件缓存目录(File sdfile = getExternalFilesDir(null);)/storage/emulated/0/Android/data/[packagename]/files。 一些重要性不高的file cache或者大文件放到这里 

    三、 android中常用的路径:

    String dataDirectory = Environment. getDataDirectory().getAbsolutePath();
    String externalStorageDirectory = Environment.getExternalStorageDirectory().getAbsolutePath();
    String filePath = getFilesDir().getAbsolutePath();
    String packageResourcePath = getPackageResourcePath();
    String cachePath = getCacheDir().getAbsolutePath();
    String databasePath = getDatabasePath("BookStore.db").getAbsolutePath();
    
    结果:
    /data
    /storage/emulated/0
    /data/data/com.example.linux.componentattributetest/files
    /data/app/com.example.linux.componentattributetest-1.apk
    /data/data/com.example.linux.componentattributetest/cache
    /data/data/com.example.linux.componentattributetest/databases/BookStore.db

    友情链接

  • 相关阅读:
    80x86的保护模式
    计算机二进制的表示
    操作系统基本知识(一)
    记录一次在安装双系统的过程(先有debian, 后加windows 8.1)
    LitePal + Gson + Volley的ORM框架尝试方案
    如何使用DDMS Heap查看Android应用内存情况
    测试驱动开发的第一个例子---我的毕业设计
    策略模式的孪生兄弟---状态模式
    面试常备---栈和队列总结篇
    面试常备题---二叉树总结篇
  • 原文地址:https://www.cnblogs.com/huhx/p/savefile.html
Copyright © 2011-2022 走看看