Android数据存储

用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");  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值