Android Preference儲存、res/raw、asset、openFileOutput、sdcard儲存、Cache詳解
*res/raw、assets、其它儲存的相同點:
1.兩者目錄下的檔案在打包後會原封不動的儲存在apk包中,不會被編譯成二進位制。
2.兩者都是隻讀,是不能儲存資料的目錄。
3.相同都可以放檔案。
*res/raw、assets、其它儲存的不同點:
1.res/raw中的檔案會被對映到R.java檔案中,訪問的時候直接使用資源ID即R.id.filename;assets資料夾下的檔案不會被對映到R.java中,訪問的時候需要AssetManager類。
2.res/raw不可以有目錄結構,而assets則可以有目錄結構,也就是assets目錄下可以再建立資料夾.
3.raw、assets不可以寫操作,只是其它可以執行寫操作。
4.openFileOutput是儲存在data/data/應用/file目錄儲存,與res/raw、assets區別是可以執行寫操作,與sdcard儲存、Cache區別是應用自己儲存,非root系統無法訪問此檔案。
5.sdcard是儲存外接空間目錄儲存,與res/raw、assets區別是可以執行寫操作,所有應用都可以訪問此目錄。
6.Cache是儲存在自己cache目錄下面,當系統空間不足,系統會清除cache儲存資料,區別就是這裡面數據不是持久儲存。
其實>http://www.cnblogs.com/yaozhongxiao/archive/2013/04/21/3034260.html )
從上面對比apk目錄結構和應用安裝好之後在應用的私有目錄存在的檔案資訊,我們發現lib已經存在於應用的私有目錄下面,那assets去哪裡了呢?
如果,我們仔細觀察下,就可以發現,打包成apk並在手機上安裝之後,該應用在手機上會存在如下幾個地發,
1)××.apk 檔案放在了/data/app/目錄下
2)/data/system/packages.xml 中增加了條記錄
3)/data/data/packagename/, 下增加了個apk使用到的私有資料
assets是不是偷懶了,assets還存在/data/app/××.apk裡面,沒有到私有目錄下面呢? 是的,就是這樣
3.讀取raw檔案方法如下,讀檔案為輸入流資料。
InputStream is = getResources().openRawResource(R.id.filename);
4.讀取assets下的檔案資源,先通過獲取AssetManager管理器,然後開啟指定檔名。
- AssetManager am = null;
- am = getAssets();
- InputStream is = am.open("filename");
5.Preference檔案儲存詳解如下:
Preference(配置)提供了一種輕量級的資料存取方法,主要應用於資料比較少的配置資訊。它以“key-value”(是一個Map)對的方式將資料儲存在一個XML配置檔案中,例如,手機的開機問候語,可以將其以Preference方式來進行配置。也可以儲存一些使用者個性化設定的字型、顏色、位置等引數資訊.
使用到的介面:
SharedPreferences介面和SharedPreferences.Editor介面,它們都是來自於andorid.content包。
①SharedPreferences介面提供儲存資料的方法
我們可以呼叫Context.getSharedPreferences(String> MODE_PRIVATE(私有)
MODE_WORLD_READABLE(可讀) MODE_WORLD_WRITEABLE(可寫)/** * SharedPreferences管理類 * */ public class SharedPreferencesMgr { private static Context context; private static SharedPreferences sPrefs ; private SharedPreferencesMgr(Context context,String fileName) { this.context=context; //初始化一個SharedPreferences物件,可以讀寫。 sPrefs= context.getSharedPreferences( fileName, Context.MODE_WORLD_READABLE ); } public static void init(Context context,String fileName) { new SharedPreferencesMgr(context,fileName); } public static String fileName ; /** * 從Preferences快取得到一個整形 * @param key * @param defaultValue * @return */ public static int getInt(String key,int defaultValue) { return sPrefs.getInt(key, defaultValue); } /** * 儲存一個整形到Preferences中 * @param key * @param value */ public static void setInt(String key,int value) { sPrefs.edit().putInt(key, value).commit(); } public static boolean getBoolean(String key,boolean defaultValue) { return sPrefs.getBoolean(key, defaultValue); } public static void setBoolean(String key,boolean value) { sPrefs.edit().putBoolean(key, value).commit(); } public static String getString(String key,String defaultValue) { if(sPrefs ==null) return null; return sPrefs.getString(key, defaultValue); } public static void setString(String key,String value) { if(sPrefs ==null) return ; sPrefs.edit().putString(key, value).commit(); } }
6.Data目錄下自己File檔案儲存詳解如下:
openFileOutput(“a.txt”,Context.MODE_WORLD_READABLE)方法第一個引數是檔名,若不存在這個檔案,則自動建立,第二個引數是操作模式共四種:
Context.MODE_PRIVATE = 0
Context.MODE_APPEND = 32768
Context.MODE_WORLD_READABLE = 1
Context.MODE_WORLD_WRITEABLE = 2
Context.MODE_PRIVATE:為預設操作模式,代表該檔案是私有資料,只能被應用本身訪問,在該模式下,寫入的內容會覆蓋原檔案的內容,如果想把新寫入的內容追加到原檔案中。可以使用Context.MODE_APPEND
Context.MODE_APPEND:模式會檢查檔案是否存在,存在就往檔案追加內容,否則就建立新檔案。
Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用來控制其他應用是否有許可權讀寫該檔案。
MODE_WORLD_READABLE:表示當前檔案可以被其他應用讀取;MODE_WORLD_WRITEABLE:表示當前檔案可以被其他應用寫入。
如果希望檔案被其他應用讀和寫,可以傳入:
openFileOutput(“itcast.txt”, Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
例子如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="請您輸入要儲存的內容:" /> <EditText android:id="@+id/addText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="請您在此處輸入檔案內容!" /> <Button android:id="@+id/addButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="save" /> <Button android:id="@+id/showButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="show" /> <TextView android:id="@+id/showText" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
package cn.com.file; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class FileTest extends Activity { private EditText editText; private TextView showTextView; // 要儲存的檔名 private String fileName = "chenzheng_java.txt"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 獲取頁面中的元件 editText = (EditText) findViewById(R.id.addText); showTextView = (TextView) findViewById(R.id.showText); Button addButton = (Button) this.findViewById(R.id.addButton); Button showButton = (Button) this.findViewById(R.id.showButton); // 繫結單擊事件 addButton.setOnClickListener(listener); showButton.setOnClickListener(listener); } // 宣告監聽器 private View.OnClickListener listener = new OnClickListener() { public void onClick(View v) { Button view = (Button) v; switch (view.getId()) { case R.id.addButton: save(); break; case R.id.showButton: read(); break; } } }; /** *@author chenzheng_Java *儲存使用者輸入的內容到檔案 */ private void save() { String content = editText.getText().toString(); try { /* 根據使用者提供的檔名,以及檔案的應用模式,開啟一個輸出流.檔案不存系統會為你建立一個的, * 至於為什麼這個地方還有FileNotFoundException丟擲,我也比較納悶。在Context中是這樣定義的 * public abstract FileOutputStream openFileOutput(String name, int mode) * throws FileNotFoundException; * openFileOutput(String name, int mode); * 第一個引數,代表檔名稱,注意這裡的檔名稱不能包括任何的/或者/這種分隔符,只能是檔名 * 該檔案會被儲存在/data/data/應用名稱/files/chenzheng_java.txt * 第二個引數,代表檔案的操作模式 * MODE_PRIVATE 私有(只能建立它的應用訪問) 重複寫入時會檔案覆蓋 * MODE_APPEND 私有 重複寫入時會在檔案的末尾進行追加,而不是覆蓋掉原來的檔案 * MODE_WORLD_READABLE 公用 可讀 * MODE_WORLD_WRITEABLE 公用 可讀寫 * */ FileOutputStream outputStream = openFileOutput(fileName, Activity.MODE_PRIVATE); outputStream.write(content.getBytes()); outputStream.flush(); outputStream.close(); Toast.makeText(FileTest.this, "儲存成功", Toast.LENGTH_LONG).show(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * @author chenzheng_java * 讀取剛才使用者儲存的內容 */ private void read() { try { FileInputStream inputStream = this.openFileInput(fileName); byte[] bytes = new byte[1024]; ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream(); while (inputStream.read(bytes) != -1) { arrayOutputStream.write(bytes, 0, bytes.length); } inputStream.close(); arrayOutputStream.close(); String content = new String(arrayOutputStream.toByteArray()); showTextView.setText(content); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }