Android SD卡存储
原创文章,转载请注明出处:http://www.cnblogs.com/baipengzhan/p/Android_SDcard_store.html
一 概念
SD卡存储空间比较大,当需要存取较大的文件时,可以使用SD卡存储。
二 特点
1, 权限
SD卡进行读取工作时,和sharedPreferences存储,File存储有权限方面的区别,主要使用以下权限:
① SDCard中创建与删除文件权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
② 从SDCard中读取文件的权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
③ 向SDCard中写入文件的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2, SD卡状态
对SD卡进行操作之前应该首先判断SD卡的各种状态,便于之后的操作。
① 判断SDcard是否“存在并且可以进行读写”
使用Environment类中的方法getExternalStorageState()获得SD卡状态,若得到的值为MEDIA_MOUNTED,则代表目前SD卡“存在并且可以进行读写”。
此处只列出最常用的状态判断值,还存在其他状态值,此处不列出。
3, 路径
使用以下方法可以获得SD卡存储路径,使用此路径会将文件存放到/mnt/sdcard文件夹中:
Environment.getExternalStorageDirectory();
4, 使用
对SD卡中文件的读和写所依据的原理为最常用的IO流操作,删除文件的方法采用File类的delete()方法。
三 Android实例
为充分理解以上内容,创建一个Android工程进行实践。
1 布局及功能介绍
Android的主Activity界面如下所示:
(描述的控件顺序从上到下)
第一个EditText输入要保存的内容;
第二个EditText输入要保存的文件名(注意同时写入文件的后缀);
点击第一个Button则保存文件,位置为/mnt/sdcard
第三个EditText输入要读取的文件名;
点击第二个Button则读取文件;
读取的文件内容显示在第一个TextView中;
第四个EditText输入要删除的文件名;
点击第三个Button则删除文件。
2 主要代码
①MainActivity.java
package com.example.sdcardoperation; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStreamReader; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private EditText et_save; private TextView tv_read; private EditText et_save_filename; private EditText et_read_filename; private EditText et_delete_filename; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_save = (EditText) findViewById(R.id.et_save); tv_read = (TextView) findViewById(R.id.tv_read); et_save_filename = (EditText) findViewById(R.id.et_save_filename); et_read_filename = (EditText) findViewById(R.id.et_read_filename); et_delete_filename = (EditText) findViewById(R.id.et_delete_filename); } //设置保存点击事件 public void save(View v) { //获得输入框中的内容 //非空判断 if(et_save.getText() == null || et_save.getText().length() <= 0 || et_save_filename.getText() == null || et_save_filename.getText().length() <= 0) { Toast.makeText(getApplicationContext(), "文件名和输入内容不能为空", Toast.LENGTH_SHORT).show(); }else { //获取待保存的文件名和保存内容,均为非空 String content_save = et_save.getText().toString().trim(); String filename_save = et_save_filename.getText().toString().trim(); //判断SD卡的状态,依据状态进行不同操作 if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { //说明sdcard存在且可以读写,进行文件存储 //获取文件 File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath().toString().trim(),filename_save.trim()); //使用输出流写文件 try { FileOutputStream fos = new FileOutputStream(file); fos.write(content_save.getBytes()); fos.close();//记得关流 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }else { Toast.makeText(getApplicationContext(), "SD卡不存在或状态异常,不能写入", Toast.LENGTH_SHORT).show(); } } } //设置读取点击事件 public void read(View v) { //首先清空上次残留的内容 tv_read.setText(""); //获取要读取的文件名 //非空判断 if(et_read_filename.getText() == null || et_read_filename.getText().length() <= 0) { Toast.makeText(getApplicationContext(), "要读取的文件名不能为空", Toast.LENGTH_SHORT).show(); }else { //首先获取文件 String filename_read = et_read_filename.getText().toString().trim(); File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath().toString().trim(),filename_read.trim()); //判断SD卡状态 if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(Environment.getExternalStorageState())) { //判断文件是否存在 if(file.exists()) { //如果文件存在,则进行读取 //创建输入流 try { FileInputStream fis = new FileInputStream(file); //开始读取数据,为了展示内容使用内存输出流 ByteArrayOutputStream baos = new ByteArrayOutputStream(); int len = -1; byte[] buffer = new byte[1024]; while((len = fis.read(buffer)) != -1) { baos.write(buffer, 0, len); } //读取完毕,关流 fis.close(); //将内存输出流中的数据显示到界面上 tv_read.setText(baos.toString()); } catch (Exception e) { Toast.makeText(getApplicationContext(), "发生异常,读取文件失败", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } }else { Toast.makeText(getApplicationContext(), "您查找的文件不存在", Toast.LENGTH_SHORT).show(); } }else { Toast.makeText(getApplicationContext(), "SD卡没有装载或目前状态不支持读取", Toast.LENGTH_SHORT).show(); } } } //设置删除点击事件 public void delete(View v) { //首先获取要删除的文件名 //非空判断 if(et_delete_filename.getText() == null || et_delete_filename.getText().length() <= 0) { Toast.makeText(getApplicationContext(), "要删除的文件名不能为空", Toast.LENGTH_SHORT).show(); }else { //获取要删除的文件名 String filename_delete = et_delete_filename.getText().toString().trim(); File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath().toString().trim(),filename_delete.trim()); //删除数据 boolean deleteFile = file.delete(); if(deleteFile) { Toast.makeText(getApplicationContext(), "删除文件成功", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(getApplicationContext(), "删除文件失败", Toast.LENGTH_SHORT).show(); } } } }
②activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:gravity="right" android:orientation="vertical" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tv_hint" /> <EditText android:id="@+id/et_save" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="12sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tv_hint2" /> <EditText android:id="@+id/et_save_filename" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="12sp" /> <Button android:id="@+id/bt_save" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="save" android:textSize="12sp" android:text="@string/text_bt_save" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tv_hint3" /> <EditText android:id="@+id/et_read_filename" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="12sp" /> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/tv_read" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/text_read" /> </ScrollView> <Button android:id="@+id/bt_read" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12sp" android:onClick="read" android:text="@string/text_bt_read" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tv_hint4" /> <EditText android:id="@+id/et_delete_filename" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="12sp" /> <Button android:id="@+id/bt_delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12sp" android:onClick="delete" android:text="@string/text_bt_delete" /> </LinearLayout>