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(原子性、一致性、隔离性、持久性)的关联式数据库管理系统,多用于嵌入式开发中。

 

唯一例外的是: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()方法则回滚事务