首页 > 代码库 > Android Preference存储、res/raw、asset、openFileOutput、sdcard存储、Cache详解
Android Preference存储、res/raw、asset、openFileOutput、sdcard存储、Cache详解
-
*res/raw、assets、其它存储的相同点:
- 两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
- 两者都是只读,是不能存储数据的目录。
- 相同都可以放文件。
- *res/raw、assets、其它存储的不同点:
- res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
- res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹.
- raw、assets不可以写操作,只是其它可以执行写操作。
- openFileOutput是存储在data/data/应用/file目录存储,与res/raw、assets区别是可以执行写操作,与sdcard存储、Cache区别是应用自己存储,非root系统无法访问此文件。
- sdcard是存储外置空间目录存储,与res/raw、assets区别是可以执行写操作,所有应用都可以访问此目录。
- Cache是存储在自己cache目录下面,当系统空间不足,系统会清除cache存储数据,区别就是这里面数据不是持久存储。
从上面对比apk目录结构和应用安装好之后在应用的私有目录存在的文件信息,我们发现lib已经存在于应用的私有目录下面,那assets去哪里了呢?
如果,我们仔细观察下,就可以发现,打包成apk并在手机上安装之后,该应用在手机上会存在如下几个地发,
1)××.apk 文件放在了/data/app/目录下
2)/data/system/packages.xml 中增加了条记录
3)/data/data/packagename/, 下增加了个apk使用到的私有数据
assets是不是偷懒了,assets还存在/data/app/××.apk里面,没有到私有目录下面呢? 是的,就是这样.
-
读取raw文件方法如下,读文件为输入流数据。
InputStream is = getResources().openRawResource(R.id.filename);
-
读取assets下的文件资源,先通过获取AssetManager管理器,然后打开指定文件名。
- AssetManager am = null;
- am = getAssets();
- InputStream is = am.open("filename");
-
Preference文件存储详解
Preference(配置)提供了一种轻量级的数据存取方法,主要应用于数据比较少的配置信息。它以“key-value”(是一个Map)对的方式将数据保存在一个XML配置文件中,例如,手机的开机问候语,可以将其以Preference方式来进行配置。也可以保存一些用户个性化设置的字体、颜色、位置等参数信息.
使用到的接口:
SharedPreferences接口和SharedPreferences.Editor接口,它们都是来自于andorid.conten包。SharedPreferences接口提供保存数据的方法.
我们可以调用Context.getSharedPreferences(String> MODE_PRIVATE(私有)
- 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(); } }
-
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(); } } }