Android下的文件、数据、数据库

10 篇文章 0 订阅

1 权限

从DDMS的File Explorer中的Permissions可以看出Android文件目录的权限。


与Linux下的文件权限表示方式相同,共用10位代表用户权限,

第1位:代表文件类型

-  文件

l  链接或快捷方式link

d  目录dir

第2~4位:代表当前用户的权限

r  readable

w  writeable

x  可执行

---  即不可读也不可写

第5~7位:代表用户所在组的权限

r  readable

w  writeable

x  可执行

---  即不可读也不可写

第8~10位:代表其他用户

r  readable

w  writeable

x  可执行

---  即不可读也不可写

在Android中为每个应用程序创建一个独立的用户,并为该用户创建一个独立的用户组。

2 手机内部文件的存取

在Android下的文件存取操作和Windows下的操作基本上没有区别,都可以通过绝对路径访问文件,区别在于Android下的某些路径有权限问题。Android为每个应用程序都创建了单独的文件存取路径,该路径为Android系统根目录下data\data\[pakageName]文件夹。应用程序包名即为文件夹名。


在应用程序中通过Context的getDir (String name, int mode)方法便可获取到该路径。此外还有getFilesDir()、getCacheDir()等方法。

下面代码可以向data\data\files\save.txt保存字符串str

File file = new File(getFilesDir(), "save.txt");
try {
    FileOutputStreamfos = new FileOutputStream(file);
    //或使用
    //FileOutputStreamfos = openFileOutput("save.txt", Context.MODE_PRIVATE);
    fos.write(str.getBytes());
    fos.flush();
    fos.close();
} catch (FileNotFoundException e) {
    // TODO Auto-generatedcatch block
    e.printStackTrace();
} catch (IOException e) {
    // TODOAuto-generated catch block
    e.printStackTrace();
}

文件读取:

File file = new File(getFilesDir(),"save.txt");
try {
    FileReaderfileReader = new FileReader(file);
    BufferedReaderbufferedReader = new BufferedReader(fileReader);
    String str= bufferedReader.readLine();
    tvRead.setText(str);
    fileReader.close();
    bufferedReader.close();
} catch (FileNotFoundException e) {
    // TODOAuto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODOAuto-generated catch block
    e.printStackTrace();
}

用上面方式创建的文件,权限为默认,即私有权限。要想创建带有指定权限的文件,可使用openFileOutput(String name, int mode)在data\data\[PakageName]\files下创建一个权限为mode的文件name。mode的值可为Context.MODE_PRIVATE、Context.MODE_WORLD_READABLE、Context.MODE_WORLD_WRITEABLE。

FileOutputStream fos =openFileOutput("save.txt", Context.MODE_PRIVATE);

3 获取存储空间大小及剩余空间

要想获取到存储空间的大小,可以先获取到存储器的簇大小,然后获取到簇的数量,两者相乘即可获得存储空间大小。

首先是SDcard:

// 判断是否有SDcard
if (Environment.MEDIA_MOUNTED.equals(Environment
       .getExternalStorageState())){
    File path= Environment.getExternalStorageDirectory();
    StatFsstatFs = new StatFs(path.getPath());
    // 获取簇大小(单位:B)
    longblockSize = statFs.getBlockSize();
    // 获取总簇数
    longblockCount = statFs.getBlockCount();
    // 获取可用簇数
    longavailableBlockCount = statFs.getAvailableBlocks();
    // 计算SDcard总大小
    longsdMemory = blockSize * blockCount;
    System.out.println(sdMemory);
    // 计算SDcard剩余大小
    longsdAvailableMemory = blockSize * availableBlockCount;
    // 格式化显示
    StringsdMemoryStr = Formatter.formatFileSize(
           MainActivity.this,sdMemory);
    StringsdAvailableMemoryStr = Formatter.formatFileSize(
           MainActivity.this,sdAvailableMemory);
    System.out.println("总大小:" + sdMemoryStr + "\n剩余空间:"
           +sdAvailableMemoryStr);
}

机身存储空间大小和SDcard大小的获取方法几乎相同,将File替换为getDataDirectory()即可。

File path = Environment.getDataDirectory();

4 SDcard文件的存取

由于Android可以通过绝对路径访问文件,所以可以使用/sdcard或/mnt/sdcard访问到SDcard,也可以使用Environment.getExternalStorageDirectory()获取到SDcard的路径/mnt/sdcard。通常在对SDcard进行访问前先检查SDcard是否存在,如果写入的文件较大,应增加对剩余空间的检查。

向SDcard写入文件:

//判断是否有SDcard
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
    String str= etWriteSDcard.getText().toString();
    File file= new File("/sdcard/save.txt");
    //或者使用
    //Filefile = new File(Environment.getExternalStorageDirectory() +"/save.txt");
    try {
       FileOutputStreamfos = new FileOutputStream(file);
       fos.write(str.getBytes());
       fos.flush();
       fos.close();
    } catch(FileNotFoundException e) {
       // TODOAuto-generated catch block
       e.printStackTrace();
    } catch(IOException e) {
       // TODOAuto-generated catch block
       e.printStackTrace();
    }
}

从SDcard读取文件:

File file = new File("/sdcard/save.txt");
try {
    FileReaderfileReader = new FileReader(file);
    BufferedReaderbufferedReader = new BufferedReader(fileReader);
    String str= bufferedReader.readLine();
    tvReadSDcard.setText(str);
} catch (FileNotFoundException e) {
    // TODOAuto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODOAuto-generated catch block
    e.printStackTrace();
}

注意:在对SDcard进行写入数据时需要权限WRITE_EXTERNAL_STORAGE

<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

在Android4.0后增加了对SDcard进行读取权限的设置,因此最好加入READ_EXTERNAL_STORAGE权限

<uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/>

5 SharedPreferences

使用SharedPreferences可以实现以键值对的形式存取任意类型数据,如使用putBoolean(String key, boolean value)保存布尔数据,使用putInt(String key, int value)保存整型数据等。SharedPreferences文件在/data/data/[PackageName]/shared_prefs下以xml文件存储。

写入:

SharedPreferences sp =getSharedPreferences("spName", MODE_PRIVATE);
//应用程序只有一个sp文件时可以不使用文件名
//SharedPreferences sp =getPreferences(MODE_PRIVATE);
Editor editor = sp.edit();
editor.putString("keyName", str);
//必须使用commit()提交才能更改
editor.commit();

读取:

SharedPreferences sp =getSharedPreferences("spName", MODE_PRIVATE);
//第二个参数为取不到key对应的value时默认的value值
String str = sp.getString("keyName","defValue");

6 SQLite数据库

在Activity中创建一个数据库非常简单,直接使用openOrCreateDatabase(String name, int mode, CursorFactory factory)即可打开或创建一个名为DB_NAME的数据库。

private static final String DB_NAME ="mydb";
private SQLiteDatabase db = null;
db = openOrCreateDatabase(DB_NAME, MODE_PRIVATE,null);

使用获取到的SQLiteDatabase对象的execSQL(String sql)方法可以执行一条标准SQL语句,可以用来创建表及其他操作。

String sql = "create table user(uid integerprimary key autoincrement, username varchar(20), password varchar(20))";
db.execSQL(sql);

插入数据:

sql = "insert into user values (?, '张三', 'password')";
db.execSQL(sql);
//或使用ContentValues
ContentValues cv = new ContentValues();
cv.put("username", "李四");
cv.put("password", "pwd12345");
db.insert("user", null, cv);

由于execSQL(String sql)没有返回值,所以不能使用该方法进行数据查询。SQLiteDatabase类提供了query()方法,query()方法有多种重载形式,可依据需要进行选择。query()方法返回一个游标cursor,可以通过该游标取得查询结果。


//select * form user
Cursor cursor = db.query("user", newString[] { "uid", "username",
       "password"}, null, null, null, null, null);
while(cursor.moveToNext())  {
    System.out.println("uid:\t"+ cursor.getInt(0));
    System.out.println("username:\t"+ cursor.getString(1));
    System.out.println("password:\t"+ cursor.getString(2));
    cursor.moveToNext();
}

数据更新:

//update user set password='12345pwd' whereusername='李四';
sql = "update user set password='12345pwd'where username='李四'";
db.execSQL(sql);
//或使用ContentValues
ContentValues cv = new ContentValues();
cv.put("password", "12345pwd");
db.update("user", cv,"username=?", new String[] {"李四"});

数据删除:

//delete from user where username='李四'
sql = "delete from user where username='李四'";
db.execSQL(sql);
//或使用delete()
db.delete("user", "username=?",new String[] {"张三"});

使用rawQuery()简化SQL语句拼接

//使用?作为占位符
sql = "select * from user where username=? andpassword like ?";
//String[]内字符串按顺序对应sql语句中的占位符
Cursor cursor = db.rawQuery(sql, newString[]{"张三", "%word%"});

此外Android还提供了对事务的支持,

db.beginTransaction();
try {
  //数据库操作
 db.setTransactionSuccessful();
} finally {
 db.endTransaction();
}

数据库操作完毕要使用close()方法将数据库关闭。

db.close();

7 使用SQLiteOpenHelper操纵SQLite数据库

Android还提供了数据库的帮助类,提供了一套自动执行的机制帮助开发者操作数据库。使用SQLiteOpenHelper需新建一个继承SQLiteOpenHelper的子类。

public classDBSQLiteOpenHelper extends SQLiteOpenHelper {
 
    private static final int DB_VERSION = 1;
    private static final String DB_NAME = "mydb";
 
    /**
     * 构造方法
     * @param context
     */
    publicDBSQLiteOpenHelper(Context context) {
       super(context,DB_NAME, null, DB_VERSION);
    }
   
    /**
     * 数据库第一次创建时自动调用该方法
     */
    @Override
    publicvoid onCreate(SQLiteDatabase db) {
       String sql = "create table user(uid integer primary keyautoincrement, username varchar(20), password varchar(20))";
       db.execSQL(sql);
    }
 
    /**
     * 版本更新时自动调用该方法,进行新数据表的创建或者旧数据表的删除或其他更新操作
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, intnewVersion) {
       Stringsql = "alter table user add age integer";
       db.execSQL(sql);
    }
 
}

在应用中需要操作数据库时,先新建一个DBSQLiteOpenHelper实例,再通过getWritableDatabase()获取到一个可写的数据库或者通过getReadableDatabase()获取到一个只读的数据库进行增删改查等操作。

DBSQLiteOpenHelper dbHelper = newDBSQLiteOpenHelper(getContext());
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.close();

8 Content Provider

使用ContentProvider可以对其他应用程序共享私有数据库。

首先在AndroidManifest.xml的Application中声明Provider标签

<!-- name标签为完整类名 -->
<!-- authorities标签随意填写,一般为<apppackagename>.provider. -->
<provider
    android:name="com.weizi.provider.DBProvider"
    android:authorities="com.weizi.provider">
</provider>

新建一个自己的Provider继承ContentProvider

public class DBProvider extendsContentProvider {
 
    //匹配指定操作URI成功时的返回值
    privatestatic final int INSERT = 1;
    privatestatic final int DELETE = 2;
    privatestatic final int UPDATE = 3;
    privatestatic final int QUERY = 4;
    privatestatic final int QUERY_TABLE_USER = 5;
    privatestatic final int DELETE_BY_UID =6;
    //URI匹配器,匹配失败返回UriMatcher.NO_MATCH
    privatestatic UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
    //增加匹配成功时的返回值
    static{
       //AndroidManifest.xml中配置的authorities
       finalString AUTHORITY = "com.weizi.provider";
       //insert操作的URIcontent://com.weizi.provider/insert
       matcher.addURI(AUTHORITY,"insert", INSERT);
       //delete操作的URIcontent://com.weizi.provider/delete
       matcher.addURI(AUTHORITY,"delete", DELETE);
       //URI也可包含要操作记录的编号或者其他数字信息content://com.weizi.provider/delete/123344
       //#表示通配所有数字,可以通过ContentUris.parseId(uri)获得该数字
       matcher.addURI(AUTHORITY,"delete/#", DELETE_BY_UID);
       //update操作的URIcontent://com.weizi.provider/update
       matcher.addURI(AUTHORITY,"update", UPDATE);
       //query操作的URIcontent://com.weizi.provider/query
       matcher.addURI(AUTHORITY,"query", QUERY);
       //URI也可包含要操作的表名content://com.weizi.provider/query/tablename
       matcher.addURI(AUTHORITY,"query/user", QUERY_TABLE_USER);
    }
 
    privateDBSQLiteOpenHelper helper;
 
    //Provivder被初始化时自动调用该方法
    @Override
    publicboolean onCreate() {
       //初始化SQLiteOpenHelper
       helper= new DBSQLiteOpenHelper(getContext());
       returntrue;
    }
 
    @Override
    publicCursor query(Uri uri, String[] projection, String selection,
           String[]selectionArgs, String sortOrder) {
       Cursorcursor = null;
       //根据传入的uri进行匹配,以确定是否为指定操作
       switch(matcher.match(uri)) {
       caseQUERY:
           //根据传入的参数对数据库进行查询操作,并返回查询得到的Cursor
           SQLiteDatabasedb = helper.getReadableDatabase();
           cursor= db.query("user", projection, selection, selectionArgs,
                  null,null, sortOrder);
           //查询完毕不要用db.close()进行关闭
           break;
       default:
           //不能匹配Uri时抛出非法参数异常
           thrownew IllegalArgumentException("Unknown Uri : " + uri);
       }
       returncursor;
    }
 
    @Override
    publicString getType(Uri uri) {
       Stringtype;
       switch(matcher.match(uri)) {
       caseINSERT:
           type= "vnd.android.cursor.item/user";
           break;
       caseDELETE:
           type= "vnd.android.cursor.item/user";
       default:
           type= null;
           break;
       }
       returntype;
    }
 
    @Override
    publicUri insert(Uri uri, ContentValues values) {
       UriinsertUri;
       //根据传入的uri进行匹配,以确定是否为指定操作
       switch(matcher.match(uri)) {
       caseINSERT:
           //插入数据记录ContentValues
           SQLiteDatabasedb = helper.getWritableDatabase();
           longrowId = db.insert("user", null, values);
           //Uri insertUri = Uri.parse("content://" + AUTHORITY +"/user" +
           //"/" + rowId);
           insertUri= ContentUris.withAppendedId(uri, rowId);
           break;
       default:
           thrownew IllegalArgumentException("Unknown Uri : " + uri);
       }
       returninsertUri;
    }
 
    @Override
    public int delete(Uri uri, String selection, String[]selectionArgs) {
       int num = 0;
       // 根据传入的uri进行匹配,以确定是否为指定操作
       switch (matcher.match(uri)) {
       case DELETE:
           // 删除指定数据记录
           SQLiteDatabase db = helper.getWritableDatabase();
           num= db.delete("user", selection, selectionArgs);
           break;
       default:
           throw new IllegalArgumentException("Unknown Uri :" + uri);
       }
       return num;
    }
 
    @Override
    public int update(Uri uri, ContentValues values, Stringselection,
           String[] selectionArgs) {
       intnum = 0;
       //根据传入的uri进行匹配,以确定是否为指定操作
       switch(matcher.match(uri)) {
       caseUPDATE:
           //更新数据记录
           SQLiteDatabasedb = helper.getWritableDatabase();
           num = db.update("user", values,selection, selectionArgs);
           break;
       default:
           thrownew IllegalArgumentException("Unknown Uri : " + uri);
       }
       returnnum;
    }
 
}

在其他应用中获取到ContentResolver的实例,然后调用其insert、update、delete、query方法并传入对应的Uri便可访问Provider提供的数据。

ContentResolver contentResolver= getContentResolver();
contentResolver.insert(url,values);
contentResolver.delete(url,where, selectionArgs);
contentResolver.update(uri,values, where, selectionArgs);
contentResolver.query(uri,projection, selection, selectionArgs, sortOrder);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值