原創文章,轉載請注明出處: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>