Android Internal and External storage 讀寫檔案(轉)

http://blog.tonycube.com/2012/03/android-internal-and-external-storage.html

1. 存在手機還是SDcard

Android可以將檔案儲存在手機上的記憶體(Internal Storage),或是外部儲存媒體 SDcard(External Storage)。
Internal storage是儲存在 /data/data/package_name/files 目錄中,每個App會有一個獨立的目錄來儲存檔案,其他App無法存取。由於是儲存在手機的記憶體中,所有會有空間的限制,不建議在這裡儲存容量太大的檔案。使用Internal storage不需要額外設定權限。

使用External Storage則必須設定讀取SDcard的權限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
儲存目錄為 /sdcard ,容量則取決於SDcard本身的容量。儲存在Internal storage時,當App被移除,所有的資料也會被移除,而External storage因為是儲存在SDcard,所以不會因為App被移除而消失。

2. 使用方法

兩者使用方式基本上都相同,只是在讀寫時會使用不同的類別。

Internal storage:

//讀檔
FileInputStream fin = this.openFileInput(filename);
//寫檔
FileOutputStream fout = this.openFileOutput(filename, Context.MODE_PRIVATE);
對Internal storage做讀寫時是使用 android.content.ContextWrapper 類別中的方法,this是指該Activity。Context.MODE_PRIVATE是指該檔案為私有的,只能由該App讀寫。另外還有其他指示性的常數,在 Context 抽象類別可以找到以 MODE_ 開頭的常數。

External storage:

//取得外部儲存媒體的目錄(這裡會是/sdcard)
String path = Environment.getExternalStorageDirectory().getPath();
//檔案路徑,記得要加斜線(這樣/sdcard/filename)
File file = new File(path + "/" + filename);
//讀檔
FileInputStream fin = new FileInputStream(file);
//寫檔
FileOutputStream fout = new FileOutputStream(file);
基本上就是使用原本的Java.io裡的類別。這樣檔案會直接儲存在SDcard下,或許你會想要建立一個自己App使用的目錄,使用的方式如下:
//先取得sdcard目錄
String path = Environment.getExternalStorageDirectory().getPath();
//利用File來設定目錄的名稱(myappdir)
File dir = new File(path + "/myappdir");
//先檢查該目錄是否存在
if (!dir.exists()){
    //若不存在則建立它
    dir.mkdir();
}
如此就會有一個 /sdcard/myappdir 的目錄產生。之後你的檔案就可以放在
File file = new File(path + "/myappdir/" + filename);
此外,在使用External storage之前,最好先檢查一下外部媒是否存在及能否讀寫。
//取得外部儲存媒體的狀態
String state = Environment.getExternalStorageState();
//判斷狀態
if (Environment.MEDIA_MOUNTED.equals(state)) {
   Log.d(TAG, "可以讀寫");
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
   Log.d(TAG, "只可以讀取,無法寫入");
} else {
   Log.d(TAG, "無法讀寫");
}

3. 程式碼

我把實際使用的程式碼寫成方法,方便使用,請依自己的需求修改,如下:

Internal storage:

//寫檔
private void writeDataToFile(String filename, String data){
  try {
    FileOutputStream fout = this.openFileOutput(filename, Context.MODE_PRIVATE);
    fout.write(data.getBytes());
    fout.close();
  } catch (FileNotFoundException e) {
    e.printStackTrace();
  } catch (IOException e) {
    e.printStackTrace();
  }
}

//讀檔
private String readDataFromFile(String filename){
  String result = null;
  try {
    StringBuilder sb = new StringBuilder();
    FileInputStream fin = this.openFileInput(filename);
    byte[] data = new byte[fin.available()];
    while (fin.read(data) != -1) {
      sb.append(new String(data));
    }
    fin.close();
    result = sb.toString();
  } catch (FileNotFoundException e) {
    e.printStackTrace();
  } catch (IOException e) {
    e.printStackTrace();
  }
return result;
}

External storage:

//寫檔到sdcard
private void writeToSDcard(String filename, String data){
   //建立自己的目錄
   String path = Environment.getExternalStorageDirectory().getPath();
   File dir = new File(path + "/movietime");
   if (!dir.exists()){
     dir.mkdir();
   }

   try {
       File file = new File(path + "/movietime/" + filename);
       FileOutputStream fout = new FileOutputStream(file);
       fout.write(data.getBytes());
       fout.close();
   } catch (FileNotFoundException e) {
       e.printStackTrace();
   } catch (IOException e) {
       e.printStackTrace();
   }
   Log.d(TAG, "Write to SDCARD!");
}

//從sdcard讀檔
private String readFromSDcard(String filename){
    String path = Environment.getExternalStorageDirectory().getPath();
    File file = new File(path + "/movietime/" + filename);
    StringBuilder sb = new StringBuilder();
    try {
        FileInputStream fin = new FileInputStream(file);
        byte[] data = new byte[fin.available()];
        while (fin.read(data) != -1) {
            sb.append(new String(data));
        }
        fin.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    Log.d("TAG", "Read from SDCARD: " + json.toString());
    return sb.toString();
}

發佈了89 篇原創文章 · 獲贊 10 · 訪問量 61萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章