Android数据存储(一)
2016-05-25 20:55
363 查看
一)文件存储方式
通过java里的文件读取流和写入流来对安卓的文件进行读写操作
安卓应用程序资源分类可以分为两大类,assets和res.其中res保存的文件大都会被编译,并且会被赋予资源id,这样我们可以在程序中通过id来访问res类的资源,res按不同用途可以分为anim,animator,color,drawable,layout,raw,menu,values,xml这九种。
1)读取assets中的文件数据:assets类资源放在工程目录的assets子目录下,它里面保存的是一些原始文件,可以以任何方式来进行组织,这些文件最终会原装不动的打包在apk文件里。
访问assets文件资源通过getAssets().open()来打开文件名,注意inputStreamReader()里面设置编码格式为utf-8,这样统一编码格式,防止乱码出现。
2)读取raw文件:raw文件和assets文件一样都是原封不动的打包在apk文件,不过raw会被赋予资源id,,这样我们就可以在程序里通过id来访问他们。
通过openRawResource()传入文件的id来访问,传入R.raw.filename
3)读写内部存储的文件数据
下面列出了两者的区别:
Internal storage:
总是可用的
这里的文件默认只能被我们的app所访问。
当用户卸载app的时候,系统会把internal内该app相关的文件都清除干净。
Internal是我们在想确保不被用户与其他app所访问的最佳存储区域。
External storage:
并不总是可用的,因为用户有时会通过USB存储模式挂载外部存储器,当取下挂载的这部分后,就无法对其进行访问了。
是大家都可以访问的,因此保存在这里的文件可能被其他程序访问。
当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
External是在不需要严格的访问权限并且希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。
我们可以读写data目录下的内部存储数据,比如我们把在EditText里面写的文字写入我们定义的一个filename,然后在data目录下可以找到filename的文件里存放着我们EditText的内容,并且可以读取出来。
模式指定为MODE_PRIVATE别的程序就不能访问这个文件。
系统默认程序的安装位置是内部,我们也可以在Manifest里面修改。当程序卸载后,其内部文件也会被删除。
我们的app的internal storage 目录以app的包名作为标识存放在Android文件系统的特定目录下[data/data/com.example.xx]。 从技术上讲,如果文件被设置为可读的,那么其他app就可以读取该internal文件。然而,其他app需要知道包名与文件名。若没有设置为可读或者可写,其他app是没有办法读写的。因此我们只要使用了MODE_PRIVATE ,那么这些文件就不可能被其他app所访问。
4)读取外部存储的文件数据
写数据到外部存储,需要声明权限(在android4.4之后外部存储的读写都不再需要声明权限)
如果声明了写权限,那么程序默认有读取的权限。
否则如果程序只需要读取的权限,我们应该声明读取权限
存储在外部的数据分为public 和private两种,public files在程序卸载时应该保留,比如被程序拍摄的照片或者下载的文件。private files在程序卸载的时候应该删除,因为这些缓存文件对其他程序来说并没有任何意义。
以public 形式向外部存储写入数据:getExternalStoragePublicDirectory()来构建一个File对象表示存储在External Storage目录,其包含一个指定文件类型的参数,以便于与其他public 文件区别,比如DIRECTORY_MUSIC和DIRECTORY_PICTURES
以private形式存储,getExternalFileDir来获取File对象,表示存储在app下的参数文件夹下,比如下面例子的(albumName)。这个文件夹会在程序卸载的时候删除。
这样将文件保存在外部存储之后,就可以进行读取的操作。
二)SharedPreference的使用
SharedPreference是一种轻型的数据存储形式,使用键值对来读写,并且通过SharedPrefrence.Editor来存储。
其存储位置在/data/data/com.xxxxxxx(package name)/shared-prefs目录。
我们可以通过getSharedPreFerences()和getPreFerences()来创建Shared Preferences文件,前者需要在参数里设置一个文件名,并且通过Context来执行;后者不需要设置文件名,而且是通过Activity来执行
sharedPreferences()的读和写操作:
通过java里的文件读取流和写入流来对安卓的文件进行读写操作
安卓应用程序资源分类可以分为两大类,assets和res.其中res保存的文件大都会被编译,并且会被赋予资源id,这样我们可以在程序中通过id来访问res类的资源,res按不同用途可以分为anim,animator,color,drawable,layout,raw,menu,values,xml这九种。
1)读取assets中的文件数据:assets类资源放在工程目录的assets子目录下,它里面保存的是一些原始文件,可以以任何方式来进行组织,这些文件最终会原装不动的打包在apk文件里。
访问assets文件资源通过getAssets().open()来打开文件名,注意inputStreamReader()里面设置编码格式为utf-8,这样统一编码格式,防止乱码出现。
@Override public void onClick(View v) { switch (v.getId()){ case R.id.get_assets: try { InputStream in=getResources().getAssets().open("info.txt"); InputStreamReader isr=new InputStreamReader(in,"utf-8"); BufferedReader bfr=new BufferedReader(isr); System.out.println(bfr.readLine()); String s=""; while ((s=bfr.readLine())!=null){//读取文件内容 System.out.println(s); } } catch (IOException e) { e.printStackTrace(); } break;
2)读取raw文件:raw文件和assets文件一样都是原封不动的打包在apk文件,不过raw会被赋予资源id,,这样我们就可以在程序里通过id来访问他们。
通过openRawResource()传入文件的id来访问,传入R.raw.filename
case R.id.get_raw: // try { // InputStream in = getResources().openRawResource(R.raw.inforaw); // InputStreamReader isr = new InputStreamReader(in, "utf-8"); // BufferedReader brf = new BufferedReader(isr); // String str = ""; // while ((str=brf.readLine())!=null){ // System.out.println(str); // } // } catch (UnsupportedEncodingException e) { // e.printStackTrace(); // }catch (IOException e){ // e.printStackTrace(); // } // break;
3)读写内部存储的文件数据
存储在内部还是外部
所有的Android设备均有两个文件存储区域:"internal" 与 "external" 。 这两个名称来自于早先的Android系统,当时大多设备都内置了不可变的内存(internal storage)及一个类似于SD card(external storage)这样的可卸载的存储部件。之后有一些设备将"internal" 与 "external" 都做成了不可卸载的内置存储,虽然如此,但是这一整块还是从逻辑上有被划分为"internal"与"external"的。只是现在不再以是否可卸载进行区分了。下面列出了两者的区别:
Internal storage:
总是可用的
这里的文件默认只能被我们的app所访问。
当用户卸载app的时候,系统会把internal内该app相关的文件都清除干净。
Internal是我们在想确保不被用户与其他app所访问的最佳存储区域。
External storage:
并不总是可用的,因为用户有时会通过USB存储模式挂载外部存储器,当取下挂载的这部分后,就无法对其进行访问了。
是大家都可以访问的,因此保存在这里的文件可能被其他程序访问。
当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
External是在不需要严格的访问权限并且希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。
我们可以读写data目录下的内部存储数据,比如我们把在EditText里面写的文字写入我们定义的一个filename,然后在data目录下可以找到filename的文件里存放着我们EditText的内容,并且可以读取出来。
模式指定为MODE_PRIVATE别的程序就不能访问这个文件。
系统默认程序的安装位置是内部,我们也可以在Manifest里面修改。当程序卸载后,其内部文件也会被删除。
我们的app的internal storage 目录以app的包名作为标识存放在Android文件系统的特定目录下[data/data/com.example.xx]。 从技术上讲,如果文件被设置为可读的,那么其他app就可以读取该internal文件。然而,其他app需要知道包名与文件名。若没有设置为可读或者可写,其他app是没有办法读写的。因此我们只要使用了MODE_PRIVATE ,那么这些文件就不可能被其他app所访问。
case R.id.get_write: try { FileOutputStream fileOutputStream=openFileOutput(filename, Context.MODE_PRIVATE); OutputStreamWriter outputStreamWriter=new OutputStreamWriter(fileOutputStream,"utf-8"); outputStreamWriter.write(write.getText().toString()); outputStreamWriter.flush(); fileOutputStream.flush(); outputStreamWriter.close(); fileOutputStream.close(); Toast.makeText(MainActivity.this,"写入完成",Toast.LENGTH_SHORT).show(); } catch (FileNotFoundException e) { }catch (UnsupportedEncodingException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } break; case R.id.read: try { FileInputStream fileInputStream=openFileInput(filename); InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream,"utf-8"); char[] input=new char[fileInputStream.available()];//文件长度设置为字符数组长度 inputStreamReader.read(input); inputStreamReader.close(); fileInputStream.close(); String str=new String(input); //字符数组转换为字符串 show.setText(str); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (UnsupportedEncodingException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } break;
4)读取外部存储的文件数据
写数据到外部存储,需要声明权限(在android4.4之后外部存储的读写都不再需要声明权限)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
如果声明了写权限,那么程序默认有读取的权限。
否则如果程序只需要读取的权限,我们应该声明读取权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>因为存储在外部的数据有可能发生变化,比如sd卡拔掉,所以在读写之前我们应该先对其可用性状态进行检查,使用getExternalStorageState()进行检查,如果返回值是MEDIA_MOUNTED,那么可以进行读写
public boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false; }如果我们只需要对程序的是否可读的状态进行检测,那么:
/* Checks if external storage is available to at least read */ public boolean isExternalStorageReadable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { return true; } return false; }
存储在外部的数据分为public 和private两种,public files在程序卸载时应该保留,比如被程序拍摄的照片或者下载的文件。private files在程序卸载的时候应该删除,因为这些缓存文件对其他程序来说并没有任何意义。
以public 形式向外部存储写入数据:getExternalStoragePublicDirectory()来构建一个File对象表示存储在External Storage目录,其包含一个指定文件类型的参数,以便于与其他public 文件区别,比如DIRECTORY_MUSIC和DIRECTORY_PICTURES
public File getAlbumStorageDir(String albumName) { // Get the directory for the user's public pictures directory. File file = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; }
以private形式存储,getExternalFileDir来获取File对象,表示存储在app下的参数文件夹下,比如下面例子的(albumName)。这个文件夹会在程序卸载的时候删除。
public File getAlbumStorageDir(Context context, String albumName) { // Get the directory for the app's private pictures directory. File file = new File(context.getExternalFilesDir( Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; }
这样将文件保存在外部存储之后,就可以进行读取的操作。
二)SharedPreference的使用
SharedPreference是一种轻型的数据存储形式,使用键值对来读写,并且通过SharedPrefrence.Editor来存储。
其存储位置在/data/data/com.xxxxxxx(package name)/shared-prefs目录。
我们可以通过getSharedPreFerences()和getPreFerences()来创建Shared Preferences文件,前者需要在参数里设置一个文件名,并且通过Context来执行;后者不需要设置文件名,而且是通过Activity来执行
private SharedPreferences preference=getPreferences(Activity.MODE_PRIVATE); private Editor editor=preference.edit();
sharedPreferences()的读和写操作:
@Override public void onClick(View v) { switch (v.getId()) { case R.id.write: editor.putString(KEY, input.getText().toString()); if (editor.commit()) { Toast.makeText(MainActivity.this, "写入数据成功",Toast.LENGTH_SHORT).show(); } break; case R.id.read: String data=preference.getString(KEY, "数据不存在"); Toast.makeText(MainActivity.this,data, Toast.LENGTH_SHORT).show(); break; default: break; } }
相关文章推荐
- Android-分辨率以及dip(dp)、dpi、ppi、px、sp、pt说明
- view的setTag() 和 getTag()应用
- Android屏幕适配方案
- android——通过 Intent 传递类对象
- [AndroidStudio]Rendering Problems
- Android adapter设计模式二:使用base-adapter-helper
- android studio 从Git拉工程 前期配置
- Android数据库 之 SQLite数据库
- Android屏幕适配总结
- AndroidCamera使用
- Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
- android默认输入法设置
- Android中Parcelable接口用法
- 如何使用ZBLibrary-Android快速开发框架
- Android电话拦截及拦截提示音的实现
- Android Studio 通过NDK调用OpenCV
- Android自定义view之ProgressBar的实现
- PullToRefreshListView
- Android自动化测试-从入门到入门(3)Espresso入门
- Android Design新特性-NavigationView实现抽屉式