Android学习笔记 --- 数据存储与访问 (File,sdcard,sharedpreferences,sqlite)

一、使用文件进行数据存储
 
    1.context.openFileOutput()方法  写入文件内容
            在上下文context中 openFileOutput方法可以用于把数据输出到文件中
    
    示例代码:
            public static void fileStorage(Context context){
              try {
                   FileOutputStream fos = context.openFileOutput("filedata.txt", context.MODE_PRIVATE);
   
                   fos.write("文件存储".getBytes());
   
                   fos.flush();
                   fos.close();
   
                  } catch (Exception e) {
                   e.printStackTrace();
             }
 }
 
openFileOutput()方法 的第一个参数用于指定文件名称,不能包含路径分隔符“/”,如果文件不存在,会自动创建,创建的文件保存在/data/data/包名/files目录下 如:/data/data/cn.itcast/files/itcast.txt
openFIleOutput()方法的第二个参数用于指定操作模式,有四种模式,分别为:
 
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用来控制其他应用是否有权限读写该文件
 
Context.MODE_WORLD_READABLE:   表示当前文件可以被其他应用程序读取
 
Context.MODE_WORLD_WRITERABLE:    表示当前文件可以被其他应用写入  
 
    如果希望文件被其他应用程序读和写,可以传入:
   openFileOutput("filestorage.text",Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
 
    Android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,当该应用要去访问其他资源时,如访文件的时候,就需要userid匹配。
    默认情况下,任何应用创建的文件,sharepreferences,数据库都应该是私有的(位于/data/data/包名/files),其他程序无法访问。除非在创建时指定了Context.MODE_WORLD_READABLE或Context.MODE_WORLD_WRITEABLE,只有这样其他程序才能正确访问。
 
    2.读取文件内容
        如果打开存放在/data/data/包名/files目录应用私有的文件,可以使用Activity提供的openFileInput()方法
 
           FileInputStream fis = context.openFileInput("fileStorage2.txt");
           BufferedReader br = new BufferedReader(new InputStreamReader(fis));
   
           String data = br.readLine();
           System.out.println("data:" + data);
 
或者直接使用该文件的绝对路径:
    File file = new File("/data/data/包名/files/文件名"):
    FileInputStream fis = new FileInputStream(file);
    
     BufferedReader br = new BufferedReader(new InputStreamReader(fis));
   
           String data = br.readLine();
           System.out.println("data:" + data);
 
    对于私有文件只能被创建该文件的应用访问,如果希望文件能被其他应用读和写,可以在创建文件时,指定Context.MODE_WORLD_READABLE 和 Context.MODE_WORLD_WRITERABLEz权限
 
Activity还提供了getCacheDir() 和 getFileDir()方法
 
    getCacheDir()方法 用于获取 /data/data/包名/cache目录   ----- 获取缓存信息
 
    getFileDir()方法 用于获取/data/data/包名/files目录
 
==================================================================================
 
二、文件存储在SDCard
 
1.存储到SDCard
    使用Activityd openFileOutput()方法保存文件,文件是存放在手机空间上,一般手机的存储孔家不是很大,存放写小文件还好,但一般不能存放大文件,如视频等
 
    在模拟器中使用SDCard,你需要先创建一个具有SDCard的模拟器
 
        在程序中访问SDCard,你需要申请访问SDCard的权限。
 
// 挂在和卸载SDCard的权限
    android.premission.MOUNT_UNMOUNT_FILESTSTEMS
 
// 写入外部存储设备的权限
    android.permission.  WRITE_EXTERNAL_STORAGE
 
    要往SDCard存放文件,程序必须先检验手机是否有SDCard的存在,并且可以进行读写。
    注意:访问SDCard必须在AndroidManifest.xml中加入访问SDCard的权限
 
    if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
       // 判断是否有sd卡 Environment.getExternalStorageState()方法用于获取SDCard的状态,
       // 如果手机装有SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED。
   
       File sdCardDir = Environment.getExternalStorageDirectory(); // 获得sdCard卡的路径
       File file = new File(sdCardDir,"sdCardStorage.txt");
   
       try {
   
        if(!file.exists()){
             // 如果文件不存在 则创建该文件
             file.createNewFile();
        }    
   
        FileOutputStream fos = new FileOutputStream(file);
        fos.write("SD卡存储".getBytes());
        fos.flush();
        fos.close();
       } catch (Exception e) {
        // TODO Auto-generated catch block
            e.printStackTrace();
       }
   
      }
    
    2.从SDCard中取出数据
 
添加从SDCard中取出数据的权限  :  android.permission.READ_EXTERNAL_STORAGE
 
    if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
           // 判断内存卡是否存在
           File sdCardDir = Environment.getExternalStorageDirectory();
           File file = new File(sdCardDir,"sdCardStorage.txt");
   
           try {
                FileInputStream fis = new FileInputStream(file);
   
                BufferedReader br = new BufferedReader(new InputStreamReader(fis));
   
                String data = br.readLine();
   
                System.out.println("data:" + data);
   
                fis.close();
                br.close();
 
               } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
               }
   
  }
 
==================================================================================
 
三、使用SharedPreferences进行数据存储
 
1.存储数据
    SharedPreferences类,是一个轻量级存储类,特别适合用于保存软件配置参数。使用SharedPreferences保存数据,其实质上是用xml文件存放数据,文件存放在/data/data/包名/shared_prefs目录下
 
    常用来保存:qq登录信息,简单的配置信息,状态,标识等。
 
      SharedPreferences sp = context.getSharedPreferences("sharedPre", context.MODE_PRIVATE);
 
      Editor editor = sp.edit(); // 获得编辑器
      editor.putString("spStorage", "SharedPreferences方式保存数据");
      editor.commit(); // 提交
 
生成的xml文件如下:
            
    <?xml version=‘1.0‘ encoding=‘utf-8‘ standalone=‘yes‘ ?>
        <map>
            <string name="spStorage">SharedPreferences方式保存数据</string>
        </map>
 
    因为SharedPreferences背后是使用xml文件保存数据,getSharedPreferences(name,mode)方法的第一个参数用于指定该文件的名称,名称后面不用带后缀.xml,后缀由Android自动加上。方法的第二个参数指定文件的操作模式,共有四种操作模式,即是前面所写的那四种模式。
 
    如果希望SharedPreferences背后使用的xml文件能被其他应用程序读和写,可以指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限。
 
    另外Activity还提供了另一个getPreferences(mode)方法操作SharedPreferences,这个方法默认使用当前类不带包名的类名作为文件的名称。
    
2.访问SharedPreferences 中的数据
 
  SharedPreferences sp = context.getSharedPreferences("sharedPre", context.MODE_PRIVATE);
  String data = sp.getString("spStorage", null);
  System.out.println("data:" + data);
 
    sp.getString(key, defValue);方法 第一个参数是键key,根据key查找对应的值value,如果没找到,则返回第二个参数defValue(默认值)
 
四、Sqlite数据库存储
    Sqlite 是一款轻型的数据库,是遵守ACID(原子性、一致性、隔离性、持久性)的关联式数据库管理系统,多用于嵌入式开发中。
 
    Sqlite的数据类型:Typelessness(物类型),可以保存任何类型的数据到你所想要保存的任何表的任何列中,但它又支持常见的类型如:NULL,VARCHAR,TEXT,INTEGER,BLOG,CLOB....等等,唯一例外的是:integer primary key 此字段只能存储64为整数
 
    在Android系统中,提供了SQLiteOpenHelper抽象类,该类用于对数据库版本进行管理,该类中常用的方法:
 
    onCreate    数据库创建时调用此方法(第一次连接获取数据库对象时执行)
 
    onUpgrade    数据库更新时调用此方法(版本号改变时执行)
 
    onOpen    数据库每次打开时执行(每次打开数据库时调用哦,在onCreate、onUpgrade方法之后
 
    1.使用SQLiteDatabase操作SQLite数据库
 
    Android提供了一个名为SQLiteDatabase的类,该类封装了一些操作数据库的API,使用该类可以完成对数据的添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete),这些操作简称为(CRUD)
 
    execSQL()方法可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句; rawQuery()方法用于执行select语句(查询query)。
 
SQLiteOpenHelper抽象类:
 
    public class MySqliteOpenHelper extends SQLiteOpenHelper {
 
         public MySqliteOpenHelper(Context context) {
                  super(context, "database.db", null, 1);
         }
 
         /**
           * 数据库创建时调用
           */
         @Override
         public void onCreate(SQLiteDatabase db) {
          
          String sql = "create table database (_id integer primary key autoincrement,name varchar(20),age varchar(20))";
          db.execSQL(sql);
         }
 
         /**
          * 数据库更新时调用
          */
         @Override
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
          // TODO Auto-generated method stub
 
         }
 
    }
 
数据库的增删改查操作:
 
         /**
          * 数据库帮助类
          */
         private MySqliteOpenHelper helper;
 
         public DatabaseUtils(Context context){
          helper = new MySqliteOpenHelper(context);
         }
 
         /**
          * 将数据插入数据库
          */
         public void insert(){
              SQLiteDatabase db = helper.getWritableDatabase();
              String sql = "insert into database values(null,‘zhangsan‘,‘20‘)";
              db.execSQL(sql);
              db.close();
 }
 
         /**
          * 更新数据库中的数据
          */
         public void update(){
              SQLiteDatabase db = helper.getWritableDatabase();
              ContentValues values = new ContentValues();
              values.put("name", "lisi");
              db.update("database", values, "name = ?", new String []{"zhangsan"});
              db.close();
     }
 
             /**
              * 查询数据库 中的数据
              */
         public void query(){
              SQLiteDatabase db = helper.getReadableDatabase();
              String sql = "select name,age from database";
              Cursor cursor = db.rawQuery(sql, null);
              while(cursor != null && cursor.moveToNext()){ // cursor 不为null 防止出现空指针异常 moveToNext ()移动到下一行
 
                  String name = cursor.getString(0); // 获得第一列的值,第一列的索引从0开始
                  int age = cursor.getInt(1); // 获得第二类的值
                  System.out.println("name : " + name + "," + "age :" + age);
          }
          cursor.close();
          db.close();
 
 }
 
         /**
          * 删除数据库中的数据
          */
         public void delete(){
              SQLiteDatabase db = helper.getWritableDatabase();
              db.delete("database", null, null);
              db.close();
     }
 
    Cursor是结果集游标,用于对结果集进行随机访问,与jdbc中的ResultSet作用很相似。使用moveToNext()方法可以将游标从当前行移动到下一行,如果已经移到了最后吧一行,返回结果为false,否则为true。另外Cursor还用常用的moveToPrevious()方法(用于将游标从当前行移动到上一行,如果已经移动到了结果集的第一行,返回值为false,否则为true)、moveToFirst()方法(用于将游标移动到结果集的第一行,如果结果集为空,返回值为false,否则为true)和moveToLast()方法(用于将游标移动到结果集的最后一行,如果结果集为空,返回值为false,否则为true);
 
使用事务操作Sqlite数据库
 
    SQLiteDatabase db = null;
          try {
           db = helper.getWritableDatabase();
           db.beginTransaction(); // 开启事务
           String sql = "insert into database values(null,‘zhangsan‘,‘20‘)";
           db.execSQL(sql);
           db.execSQL("update database set name=? where age=?", new Object[]{"wangwu", 20});
           db.setTransactionSuccessful(); // 调用此方法会在执行到endTransaction()方法时提交当前事务,如果不调用此方法会回滚事务
          }finally{
               if(db != null){
               db.endTransaction(); // 事务的结束的标志,决定是提交事务还是回滚事务
           }
      }
          db.close();
 
    使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction()方法时会检查事务的标志是否成功,如果程序执行到endTransaction()方法之前调用了setTransactionSuccessful()方法设置事务的标志为成功,则提交事务,如果没有调用setTransactionSuccessful()方法则回滚事务

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。