1. 程式人生 > >Android Preference儲存、res/raw、asset、openFileOutput、sdcard儲存、Cache詳解

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管理器,然後開啟指定檔名。

  1. AssetManager am = null;  
  2. am = getAssets();  
  3. 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();
		}

	}

}