Android数据存储方式——文件存储(内部和外部空间)

80 阅读3分钟
说明:
    核心原理: Context提供了两个方法来打开数据文件里的文件IO流 FileInputStream openFileInput(String name); FileOutputStream(String name , int mode),这两个方法第一个参数 用于指定文件名,第二个参数指定打开文件的模式。具体有以下值可选:

1、MODE_PRIVATE::为默认操作模式,代表该文件是私有数据,只能被应用本身访问,
在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。
可以使用Context.MODE_APPEND

2、MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件

3、  MODE_WORLD_READABLE:表示当前文件可以被其他应用读取。

4、MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入

文件存储位置:
a/内部存储空间
手机内置的存储空间,空间有限,可贵,安全,稳定,保存比较重要的私有数据。
一般内部存储空间文件会保存在/data/data/<package_name>/files/路径下(

存入步骤:
    1、使用Context.openFileOutput()方法获取到一个FileOutputStream对象
    2、把待写入的内容通过write()方法写入到FileOutputStream对象中
    3、调用close()方法关闭输出流

读取步骤:
    1、调用openFileInput()方法,指定文件的名字,返回一个FileInputStream流
    2、调用流的read()方法读取数据
    3、调用close()方法关闭输入流  

b/外部存储空间(SD卡)
常见的SD卡等,存储空间大,不稳定。

sd卡保存步骤:1、添加sd卡读写权限,判断sd卡状态,获取sd卡根路径
        2、新建File对象,并获取FileOutputStream
        3、把待写入的内容通过FileOutputStream流写入文件并关闭流
sd卡读取步骤:1、添加sd卡读写权限,判断sd卡状态,获取sd卡根路径
        2、根据文件路径获得File对象,并获取FileInputStream
        3、通过FileInputStream的read()方法读取数据
内部空间存储代码样例:
acvitity_main.xml

 <EditText
        android:id="@+id/et_save"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入内容"
        android:textSize="25sp" />

    <Button
        android:id="@+id/btn_save"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@android:color/darker_gray"
        android:gravity="center"
        android:text="保存"
        android:textSize="25sp" />

    <Button
        android:id="@+id/btn_read"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@android:color/darker_gray"
        android:gravity="center"
        android:text="读取"
        android:textSize="25sp" />


    <TextView
        android:id="@+id/tv_read"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:textColor="@android:color/holo_orange_dark"/>

MainAcvitity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private EditText et_save;
    private Button btn_save, btn_read;
    private TextView tv_read;
    private String name="text.txt";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intiView();
    }

    private void intiView() {
        et_save = (EditText) findViewById(R.id.et_save);
        btn_save = (Button) findViewById(R.id.btn_save);
        btn_read = (Button) findViewById(R.id.btn_read);
        tv_read = (TextView) findViewById(R.id.tv_read);
        btn_save.setOnClickListener(this);
        btn_read.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_save:
                    saveByInner();
                break;
            case R.id.btn_read:
                readByInner();
                break;

        }
    }
    //保存数据的方法
    public void saveByInner(){
        String content=et_save.getText().toString();
        try {
            FileOutputStream out=openFileOutput(name, Context.MODE_PRIVATE);//以覆盖方式保存数据
            out.write(content.getBytes());
            out.close();
            Toast.makeText(this,"已保存",Toast.LENGTH_SHORT).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //读取数据的方法
    public void readByInner(){
        try {
            FileInputStream input= openFileInput(name);
            byte[] buffer= new byte[1024];
            int length=0;
            StringBuffer sb=new StringBuffer();
            while ((length=input.read(buffer))!=-1){
                sb.append(new String(buffer,0,length));
            }
            input.close();
            tv_read.setText(sb.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
外部空间sdk卡存储代码样例:
 //sd卡保存数据的方法
    private void writeBySD(){
        //先给sdk卡添加读写权限,判断内存卡的状态
        if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//如果内存卡没有挂起
            Toast.makeText(this,"内存卡未找到!",Toast.LENGTH_SHORT).show();
            return;
        }else {//如果内存卡已经挂起可以找到,就找到根目录
            String path=Environment.getExternalStorageDirectory()+ File.separator+name;
            File file=new File(path);
            try {
                FileOutputStream write=new FileOutputStream(file);
                String content=et_save.getText().toString();
                write.write(content.getBytes());
                write.close();
                Toast.makeText(this,"SD卡存储成功!",Toast.LENGTH_SHORT).show();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //sd卡读取的方法
    private void readBySD(){
        //判断内存卡状态
        if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            Toast.makeText(this,"内存卡未找到!",Toast.LENGTH_SHORT).show();
            return;
        }else {
            String path=Environment.getExternalStorageDirectory()+File.separator+name;
            File file=new File(path);
            try {
                FileInputStream read=new FileInputStream(file);
                int length=0;
                StringBuffer sb=new StringBuffer();
                byte[] buffer=new byte[1024];
                while ((length=read.read(buffer))!=-1){
                    sb.append(new String(buffer,0,length));
                }
                read.close();
                tv_read.setText(sb.toString());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 //存储动态权限的获取,适用于安卓6.0以上的部分机型(兼容模式)
    private void checkPermission(){
        int code=ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if(code== PackageManager.PERMISSION_GRANTED){//已经有权限
            writeBySD();
        }else {//没有权限要动态获取,通过弹出的提示框让用户进行选择
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        }

    }
    //重写onRequestPermissionsResult方法

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestCode==1&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
            writeBySD();
        }else {
            Toast.makeText(this,"访问需要权限,请先获取权限",Toast.LENGTH_SHORT).show();
        }
    }