用SharedPreferences类存储轻量级数据
SharedPreferences
常用来存储一些轻量级的数据,通过存储
key-value(键值对)的xml文件实现(
实际就是存储到
/data/data/
<package name>/shared_prefs/下的
xml文件中
)
SharedPreferences提供了java常规的Int、String等类型数据的保存接口。
通过调用getSharedPreferences(name,mode
)方法或者context.getPreferences(
mode
)
去根据相关信息获取SharedPreferences对象,
SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);//xml文件名默认是调用getPreferences()的activity类名
SharedPreferences.Editor editor = sharedPref.edit();//编辑
editor.putString("key1", "value1");
editor.putString("key2", 123);
editor.commit();
String strValue = sharedPref.getString("key1", "");
int intValue = sharedPref.getString("key2", 0);
大体积数据存储到文件
两种资源文件
需要通过特定的方式进行打开使用。
res/raw下文件,已被映射到R.java文件中,访问的时候直接使用资源ID(
R.id.filename
)
获取InputStream is = getResources().openRawResource(R.raw.n
ame
);
/asset
下文件,可以设置目录
获取
InputStream is = getResources().getAssets().open(fileName);
//Resources类有getAssets
成员函数
,通过它可以获得保存在Resources类的成员变量mAssets中的AssetManager
或者AssetManager am =
getAssets();
InputStream is = am.open("filename" );
这些数据只能读不能写,并且在这些目录下的文件大小不能超过1M。
存放在数据区文件
即/data/data/
<package name>/下的
文件,只能使用
context.
openFileOutput
(fileName)
和
context.
openFileInput
(fileName)
进行操作。
(
注意不能使用FileInputStream()和FileOutputStream()进行文件的操作
)
content.
getFilesDir()方法用于获取/data/data/
<package name>
/files目录
context.getCacheDir()方法用于获取/data/data/<package name>/cache目录
openFileOutput()方法的第二参数用于指定操作模式,有四种模式,分别为:
Context.MODE_PRIVATE=0
为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容。
Context.MODE_APPEND=32768
这种模式下会先检查文件是否存在,存在就往
原
文件追加
新写入的
内容,否则就创建新文件。
Context.MODE_WORLD_READABLE=1
表示当前文件可以被其他应用读取
Context.MODE_WORLD_WRITEABLE=2
表示当前文件可以被其他应用写入
如果希望文件被其他应用读和写,可以传入:
openFileOutput(“itcast.txt”, Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,当该应用要去访问其他资源比如文件的时候,就需要userid匹配。默认情况下,任何应用创建的文件,sharedpreferences,数据库都应该是私有的(位于/data/data/<package name>/files),其他程序无法访问。除非在创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE ,只有这样其他程序才能正确访问。
SD卡中的文件
使用FileInputStream()和FileOutputStream()进行文件的操作。<!– 允许挂载和反挂载文件系统可移动存储权限 –>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS”/><!– 往SDCard写入数据权限 –>
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))//获取SDCard的状态
File sdCardDir = Environment.getExternalStorageDirectory();//获取SDCard目录
遍历Download文件夹代码:
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File[] files = file.listFiles();
for (int i = 0; i < files.length; ++i)
{Log.e(TAG, files[i].getAbsolutePath());}
File类进行文件的读写
File file = new File(fileName);
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file);
//File类常用的操作
String Name = File.getName(); //获得文件或文件夹的名称:
String parentPath = File.getParent(); //获得文件或文件夹的父目录
String path = File.getAbsoultePath();//绝对路经
String path = File.getPath();//相对路经
File.createNewFile();//建立文件
File.mkDir(); //建立文件夹
File.isDirectory(); //判断是文件或文件夹
File[] files = File.listFiles(); //列出文件夹下的所有文件和文件夹名
File.renameTo(dest); //修改文件夹和文件名
File.delete(); //删除文件夹或文件
RandomAccessFile进行文件的读写
//new RandomAccessFile(f,"rw");//读写方式
//new RandomAccessFile(f,"r");//只读方式
/*
* 程序功能:演示了RandomAccessFile类的操作,同时实现了一个文件复制操作。
*/
import java.io.*;
public class RandomAccessFileDemo {
public static void main(String[] args) throws Exception {
RandomAccessFile file = new RandomAccessFile("file", "rw");
// 以下向file文件中写数据
file.writeInt(20);// 占4个字节
file.writeDouble(8.236598);// 占8个字节
file.writeUTF("这是一个UTF字符串");// 这个长度写在当前文件指针的前两个字节处,可用readShort()读取
file.writeBoolean(true);// 占1个字节
file.writeShort(395);// 占2个字节
file.writeLong(2325451l);// 占8个字节
file.writeUTF("又是一个UTF字符串");
file.writeFloat(35.5f);// 占4个字节
file.writeChar('a');// 占2个字节
file.seek(0);// 把文件指针位置设置到文件起始处
// 以下从file文件中读数据,要注意文件指针的位置
System.out.println("——————从file文件指定位置读数据——————");
System.out.println(file.readInt());
System.out.println(file.readDouble());
System.out.println(file.readUTF());
file.skipBytes(3);// 将文件指针跳过3个字节,本例中即跳过了一个boolean值和short值。
System.out.println(file.readLong());
file.skipBytes(file.readShort()); // 跳过文件中“又是一个UTF字符串”所占字节,注意readShort()方法会移动文件指针,所以不用加2。
System.out.println(file.readFloat());
//以下演示文件复制操作
System.out.println("——————文件复制(从file到fileCopy)——————");
file.seek(0);
RandomAccessFile fileCopy=new RandomAccessFile("fileCopy","rw");
int len=(int)file.length();//取得文件长度(字节数)
byte[] b=new byte[len];
file.readFully(b);
fileCopy.write(b);
System.out.println("复制完成!");
}
}
复杂结构数据存储到SQLite数据库
SQLite3
数据库
支持存储NULL,INTEGER,REAL(浮点数),TEXT(UTF-8字符串文本),BLOB(二进制大对象)数据类型数据。
在实际开发中,为了能够更好的管理和维护数据库,我们会
通过继承
SQLiteOpenHelper类实现
自己
自定义的
DBHelper
对象:
public class DBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "test.db";
private static final int DATABASE_VERSION = 1;
public SqliteHelper(Context context, String name, CursorFactory factory, int version) {
// 调用父类构造函数
super(context, name, factory, version);
}
public SqliteHelper(Context context, String name, int version) {
//CursorFactory设置为null,使用默认值
this(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public SqliteHelper(Context context, String name) {
this(context, name, 1);
}
public DBHelper(Context context) {
}
//数据库第一次被创建时onCreate会被调用
@Override
public void onCreate(SQLiteDatabase db) {
}
//如果DATABASE_VERSION值被改为2,系统发现现有数据库版本不同,即会调用onUpgrade
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
数据库使用例子
SqliteHelper helper = new DBHelper(getApplicationContext(), "app_db");
SQLiteDatabase db = helper.getReadableDatabase();
db.excSQL("delete from main_db");
db.execSQL("insert into main(name, age) values('测试数据1', 4)");
db.execSQL("insert into person(name, age) values(?,?)", new Object[]{"测试数据2", 4});
Cursor cur = db.rawQuery("select * from main", null);
while (cur.moveToNext()) {
int personid = cur.getInt(0); //获取第一列的值,第一列的索引从0开始
String name = cur.getString(1);//获取第二列的值
int age = cur.getInt(2);//获取第三列的值
}
cur.close();
db.close();
通过getReadableDataBase()或者
getWritableDatabase()获取
SQLiteDatabase
实例。(
getWritableDatabase()方法
打开
磁盘空间已满的
数据库会报错,而
getReadableDatabase()方法不会报,但会以
只读方式打开数据库。
)
用execSQL()方法执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句;
execSQL(String sql, Object[] bindArgs)方法的第一个参数为SQL语句,第二个参数为SQL语句中占位符参数的值,参数值在数组中的顺序要和占位符的位置对应。
用rawQuery()方法用于执行select语句。rawQuery()方法的第一个参数为select语句;第二个参数为select语句中占位符参数的值,如果select语句没有使用占位符,该参数可以设置为null。
通过
Cursor
结果集游标
对象读取
rawQuery()
方法运行的SQL语句后获得的结果集。
cur.move(int offset); //以当前位置为参考,移动到指定行
cur.moveToFirst(); //移动到第一行,如果已经在第一行返回false,否则为true
cur.moveToLast(); //移动到最后一行,如果已经在最后一行返回false,否则为true
cur.moveToPosition(int position); //移动到指定行
cur.moveToPrevious(); //移动到前一行,如果已经在第一行无前一行,返回false,否则为true
cur.moveToNext(); //移动到下一行,如果已经在最后一行无下一行,返回false,否则为true
cur.isFirst(); //是否指向第一条
cur.isLast(); //是否指向最后一条
cur.isBeforeFirst(); //是否指向第一条之前
cur.isAfterLast(); //是否指向最后一条之后
cur.isNull(int columnIndex); //指定列是否为空(列基数为0)
cur.isClosed(); //游标是否已关闭
cur.getCount(); //总数据项数
cur.getPosition(); //返回当前游标所指向的行数
cur.getColumnIndex(String columnName);//返回某列名对应的列索引值
cur.getString(int columnIndex); //返回当前行指定列的值
增删改查操作
添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)操作(这些操作简称为CRUD),
可以通过
execSQL()和
rawQuery()用SQL语句实现,但
SQLiteDatabase专门提供了对应于添加、删除、更新、查询的操作方法: insert()、delete()、update()和query()
//打开或创建test.db数据库
SQLiteDatabase db = openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null);
db.execSQL("DROP TABLE IF EXISTS person");
//创建person表
db.execSQL("CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age SMALLINT)");
Person person = new Person();
person.name = "john";
person.age = 30;
//插入数据
db.execSQL("INSERT INTO person VALUES (NULL, ?, ?)", new Object[]{person.name, person.age});
person.name = "david";
person.age = 33;
//ContentValues以键值对的形式存放数据
ContentValues cv = new ContentValues();
cv.put("name", person.name);
cv.put("age", person.age);
//插入ContentValues中的数据
db.insert("person", null, cv);
cv = new ContentValues();
cv.put("age", 35);
//更新数据
db.update("person", cv, "name = ?", new String[]{"john"});
Cursor c = db.rawQuery("SELECT * FROM person WHERE age >= ?", new String[]{"33"});
while (c.moveToNext()) {
int _id = c.getInt(c.getColumnIndex("_id"));
String name = c.getString(c.getColumnIndex("name"));
int age = c.getInt(c.getColumnIndex("age"));
Log.i("db", "_id=>" + _id + ", name=>" + name + ", age=>" + age);
}
c.close();
//删除数据
db.delete("person", "age < ?", new String[]{"35"});
//关闭当前数据库
db.close();
//删除test.db数据库
//deleteDatabase("test.db");