Android数据存储之文件存储

本文介绍了Android平台上的文件存储方法,包括使用Context进行文件操作的基本流程,并对比了简单版和复杂版实现方式。同时,探讨了Android内外部存储的区别及如何合理选择存储位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

—— 大家都知道,数据和算法是一个应用程序的核心。所以,学好数据存储是非常有必要的。
——Android数据的存储有多种方式,比如ContentProvider(内容提供者)、SQLite(嵌入式数据库)存储、SharedPreferences存储、文件(File)存储等。文件(File)存储是最简单的数据存储方式,也是用得较少的一种数据存储方式。
——在这里,不知道大家有没有发现文件(File)存储似曾相识啊!没错,所谓的文件(File)存储不过是简单的Java.IO流罢了。那么,Java.IO流来到Android平台上怎么使用呢?不妨先想想,这就有点像老大来到一个有出息的小弟家做客,如果你是这个有出息的小弟,你该怎么做?不管怎样是不是先让个人去给老大带路呀!礼貌必不可少的。回到主题,为了让Java.IO流在安卓平台上起到好的发挥作用,这里需要使用Context来给老大带路!Context中都提供了相应的函数来支持,使用Context不但操作简单方便,最重要的是Context会帮助我们管理这些文件,也可以方便帮助我们控制文件的访问权限。
——了解Context的得力之处:(1)FileOutputStream out = context.openFileOutput(String filename,int mode); 以mode模式获得文件输出流,(2)out.write(byte[]b)。openFileOutput方法中有两个参数,filename是文件名(不包含路径),mode是代表模式,其中,mode模式有四种,MODE_PRIVATE:私有覆盖模式 (默认模式),MODE_APPEND:私有追加模式,注意:这两种模式只能被当前应用访问;还有两种模式在Android4.2以后被废除。默认情况下会将文件存储到/data/data//files的文件。
——很多文件存储的例子写的都不一样,你会发现一个大神写的是一样,另一个大神写的是一样,这里有必要归纳一下,一种是简单的版本(直接是上面说到的两个步骤),还有一种是复杂的版本(就是需要用到转换流和缓冲区等),根据需要来选择就好,最起码别人写的要看懂哈!知道是怎么一回事就行。下面贴出代码:
简单版:

/**
 * Created by Dell on 2017/3/22.
 */
public class MyContextFile extends Activity {
    private EditText writeFileContent;
    private TextView displayContent;
    private Button writeFileButton,readFileButton;
    private String writeinfo;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_file);
        initLayout();
    }
    private void initLayout(){
        writeFileContent=(EditText) findViewById(R.id.write_Edit);
        displayContent=(TextView) findViewById(R.id.display_textView);
        writeFileButton=(Button) findViewById(R.id.write_Button);
        readFileButton=(Button) findViewById(R.id.read_Button);
        writeFileButton.setOnClickListener(writeFileClickListener);
        readFileButton.setOnClickListener(readFileClickListener);
    }
    //将输入的信息写入到文件中
    View.OnClickListener writeFileClickListener=new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //通过EditText获得输入的信息
            writeinfo=writeFileContent.getText().toString();
            FileOutputStream fileOutputStream=null;
            try {
                //通过openFileOutput()方法得的一个文件输出流
                fileOutputStream=openFileOutput("user.txt",MODE_PRIVATE);
                //将输入的信息写入到文件
                fileOutputStream.write(writeinfo.getBytes());
                Toast.makeText(MyContextFile.this, "写入文件成功",
                        Toast.LENGTH_SHORT).show();
            }catch (FileNotFoundException e){
                e.printStackTrace();
            }catch (IOException e){
                e.printStackTrace();
            }finally {
                if (fileOutputStream!=null){
                    try {
                        fileOutputStream.close();//关闭文件流
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                    fileOutputStream=null;
                }
            }
        }
    };
    //读取文件中的信息
    View.OnClickListener readFileClickListener=new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FileInputStream fileInputStream=null;
            try {
                //通过openFileOutput()方法得的一个文件写入流
                fileInputStream=openFileInput("user.txt");
                //定义一个字节数组来缓存读取的字节
                byte[] cache=new byte[fileInputStream.available()];
                //读取文件
                fileInputStream.read(cache);
                displayContent.setText(":"+new String(cache));
            }catch (FileNotFoundException e){
                e.printStackTrace();
            }catch (IOException e){
                e.printStackTrace();
            }finally {
                if (fileInputStream!=null){
                    try {
                        fileInputStream.close();//关闭文件流
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                    fileInputStream=null;
                }
            }
        }
    };
}

复杂版:

package com.xhm.demo.myandroidsql;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * Created by Dell on 2017/3/22.
 */
public class FileContext extends Activity {
    String data="data";
    FileOutputStream out=null;
    BufferedWriter bw=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            //调用Context.openFileOutput()方法获得java文件
            // 输出流(FileOutputStream)并返回对象
            out=openFileOutput("data", Context.MODE_PRIVATE);
            //借助FileOutputStream构建出一个OutputStreamWriter对象
            OutputStreamWriter osw=new OutputStreamWriter(out);
            //借助OutputStreamWriter构建出一个BufferedWriter对象
            bw=new BufferedWriter(osw);
            bw.write(data);//写内容  
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if (bw!=null){
                    bw.close();//关闭文件流
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

——是不是觉得安卓文件存储很简单呀!是它和Java.IO流有关系而简单,也是因为它和Java.IO流有关系而复杂。上面的例子都是在安卓存储理想状态下执行的,请问你了解安卓的数据存储情况吗?有那些分类,各有什么不同、采取什么方式等等?
——学习就像考虑事情一样要周。接下来了解一下安卓的存储情况吧!Android存储空间分为内部存储空间(Internal Storage)和外部存储空间(External Storage)。简单的说就是手机内存和SD卡这两种存储空间。内部存储空间十分有限,因而显得可贵,所以我们要尽可能避免使用;另外,它也是系统本身和系统应用程序主要的数据存储所在地,一旦内部存储空间耗尽,手机 也就无法使用了。 使用内部存储主要有二个方式,一个是文件操作,一个是文件夹操作。注意:尤其是在开发应用程序是要为手机用户解应用数据到底存在哪里好?想想如果把手机用户的内存存了很多数据,内存用完用户会反感的,那如果我们把数据存到SD卡安全数不高也会引来用户的反感。那怎么办呢?这是值得考虑的,实在不行我们采取中庸之道,在存储数据之前我们先来判断用户手机内存和SD卡还剩多少内存,把数据存到内存最多的那个地方去,不痛不痒,妙
1.需要判断sd卡是否可用:

/**
 * Check if the primary "external" storage device is available.
 * 
 * @return
 */
public static boolean hasSDCardMounted() {
    String state = Environment.getExternalStorageState();
    if (state != null && state.equals(Environment.MEDIA_MOUNTED)) {
        return true;
    } else {
        return false;
    }
}

2.应用数据存放路径,同其他应用应该保持一致,应用卸载时,清除数据:
3.需要判断两者的可用空间:在API level 9及其以上时,File对象的getFreeSpace()方法获取系统root用户可用空间;
getUsableSpace()取非root用户可用空间。当有多个存储可用时获取磁盘用量,根据当前系统情况选用合适的存储。
根据系统存储用量,合理设定app所用的空间大小;运行时,也可做动态调整。

@TargetApi(VERSION_CODES.GINGERBREAD)
public static long getUsableSpace(File path) {
    if (path == null) {
        return -1;
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
        return path.getUsableSpace();
    } else {
        if (!path.exists()) {
            return 0;
        } else {
            final StatFs stats = new StatFs(path.getPath());
            return (long) stats.getBlockSize() * (long) stats.getAvailableBlocks();
        }
    }
}

——内部存储的唯一缺点就是空间有限、珍贵;最大的有点就是安全数高(只允许本应用程序访问,且一旦删除应用程序,数据一会跟着被删除)。外部存储空间是指手机出厂的时候不存在,用户在使用时候可以自由添加的外部存储介质比如TS卡,SD卡等闪存储介质。其实安卓系统它是要依赖于外部存储卡的,因为对于Android系统,如果没有外部存储卡,很多 的系统应用无法使用,比如多媒体相关的应用程序无法使用。优点就是存储空间大,不用担心去清除数据。外部存储的缺点就是不是很稳定,对于Android手机来讲可以说,很不稳定,本身闪存介质就容易出问 题,SD卡处于不能正常使用的状态十分多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值