安卓文件存储数据特点
1. Android数据存储方式有什么不同
SharedPreferences共享偏好
只能存储一些Key/Value类似的成对的基本数据类型,所以一般用来保存配置(Settings)信息。使用简单方便;Internal Storage内部存储空间
即设备出产前设定的储存空间,一般安装应用就安装在此。比较稳定,存储方便,操作简单,更加安全(因为可以控制访问权限)等优点。而它唯一的缺点就是它比较有限,比较可贵。
External Storage外部存储空间
类似SD卡以及一些扩展存储,方便用户存放更多的数据,如音乐下载,视频等。存储在外部存储卡上的数据是所有应用程序都可见,用户也可见(使用FileManager)。外部存储卡不是随时想用就能够用的,所以一定要记得在使用之前检查它的可用性。
SQLite Database数据库
是Android自带的一个小型数据库。效率出众,这是无可否认的。十分适合存储结构化数据。方便在不同的Activity,甚至不同的应用之间传递数据。由专门的ContentProvider来帮忙管理和维护数据库
Internet网络
网络是比较不靠谱的一个,因为移动终端的网络稳定性,以及所产生的流量让人伤不起,用户更伤不起。但若是对于非常重要的实时数据,或是需要发送给远端服务器处理的,也可以考虑使用网络实时发送。
综上,
1. 简单数据和配置信息,SharedPreference是首选;
2. 如果SharedPreferences不够用,那么就创建一个数据库
3.
结构化数据,一定要创建数据库,虽然这稍显烦锁,但是好处无穷
4.
文件就是用来存储文件(也即非配置信息或结构化数据),如文本文件,二进制文件,PC文件,多媒体文件,下载的文件等等。
5. 尽量不要创建文件
6.
如果创建文件,如果是私密文件或是重要文件,就存储在内部存储,否则放到外部存储
7.
不要收集用户数据,更不要发到网络上,虽然你们也有很多无奈。用户也无奈,也无辜,但更无助
平台为开发者准备了这么多的方式固然是一件好事,但我们要认清每一种的优点和缺点,根据实际情况选择最合适的。还有一个原则就是最简单原则,也就是说能用简单的方式处理,就不要用复杂的方式。比如存储几个数据或简单对象,用SharedPreference也能做到,何必还去写个ContentProvider呢?参考自:http://www.jb51.net/article/37225.htm
2. 安卓内外部存储完全解析 -- 别再弄混了
安卓开发离不开手机存储,然而大部分人对于安卓开发中的存储概念存在误区,内部外部SD卡傻傻分不清?
以下引用来自对 官方文档 的理解
呵呵呵,先别说话,然而重点来了(敲黑板),按照官方的说法,
内部存储是指系统的存储空间,没有root是访问不到的呦亲,比如sharedPreferenced或者database都是保存在这里面的。
外部存储,又分为 2 部分:
然而现实中,常常有同事把手机那个32G,64G存储叫做内部存储= =,宝宝好累,人家明明是 ExternalStorage !!
希望本篇能让大家对内外部存储有一个正确鲜明的认识
getFilesDir()
路径如下
文档 云:若想操作该路径,你需要一个输出流:
就像这样:
注: this 是 context 对象
在
路径下会看到新文件哦
如果你还想读取的话, 文档 云:你需要一个输入流:
Log如下
getCacheDir()
文档 云:
路径如下:
特别的,还有getDir() :
getDir("- -!.txt", Context.MODE_PRIVATE).getAbsolutePath()
路径如下:
app_是系统自己加上去的
内部存储就是系统的存储,没有root你是看不到的,内部存储最大特点就是可以用Context对象调用各个获取路径的方法。比如: context.fileList()
那就是
下的文件遍历。
而 deleteFile("ABC") 就是
删除下名为 ABC 的文件
</br></br></br>
操作外部存储你首先需要以下权限
当你申请了write权限,那么read权限默认也就通过啦
再判断状态:
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState))
Environment.getExternalStorageDirectory()
这个路径根据手机厂家不同会有些许变化
直接传入 Environment 中的常量获取相应的路径,如下:
Environment.(Environment.DIRECTORY_ALARMS));
或者
Environment.(Environment.DIRECTORY_PICTURES));
公有目录下,系统会区分不同类别 (例如铃声在系统设置中显示为铃声而不是音乐)
4.4以后访问该目录不再需要权限了
getExternalFilesDir(String type)
eg.
getExternalFilesDir(Environment.DIRECTORY_MUSIC)
特别的:ContextCompat下的
ContextCompat.getExternalFilesDirs(context,type)
返回一个File[],在4.4以后第一条数据默认外部主存储目录,第二条数据就是sd卡路径啦,但是注意4.4之前是没有第二条数据的哦
该目录下的特点是卸载程序后,该目录和其下所有文件均会被删除
getExternalCacheDir()
注意,使用该目录注意管理空间,你不能等系统帮你清理,而是自己清理不再需要的缓存
特别的:ContextCompat下的
ContextCompat.getExternalCacheDirs()
道理同上
发现特点了吗朋友,无论外部内部,只有路径中有包名,那么就是私有的,而且是随着程序的卸载而被删除的, 有包名的路径均是Context中的方法,而公有的路径均是Environment调用的
这个货真真是要了老命,一般的方法根部不好使,结合网上有的方法加上公司项目中的方法,总结如下:
百分百好用的获取SD卡路径方法:
最后集合 path 中的值就是SD卡根目录
虽然无视版本百分百好用,但是如果你的手机有SD卡槽却没插SD卡,该方法最后 path 返回的是 null ,也就是说该方法无法判断到底是没插SD卡还是根本不支持SD卡
其实还有一种方法
String path = System.getenv("SECONDARY_STORAGE");
该方法只要你手机支持SD卡,无论你插没插SD卡,均会返回SD卡路径,但是 6.0及以上该方法被移除
Environment中源码其实就是根据这个方法获取路径的
安卓官方文档大家一定要看,他就是我们开发者的权威呀,圣经呀!!
3. android提供的数据存储方式有几种
对于Android平台来讲,它的存储方式也不外乎这几种,按方式总体来分,也是文件,数据库和网络。但从开发者的角度来讲它可以分为以下五种方式:
1.SharedPreferences共享偏好
2.Internal Storage内部存储空间
3.External Storage外部存储空间
4.SQLite Database数据库
5.Internet网络
这几种方式各自有各自的优点和缺点,要根据不同的实际情况来选择,而无法给出统一的标准。
如果想要了解可以继续追问,满意请采纳。
4. 安卓的存储机制
安卓的文件存储分为内部存储和外部存储,在安卓早期,手机内置存储很小,都是用于应用的私有存储空间,外部存储就是sdcard。往后发展,手机的内置存储越来越大,同时也出现了一些不支持sdcard的手机。如今安卓的外部存储已经不限于sdcard了。
内部存储
手机内部存储除了放置应用的私有和系统空间以外都为外部存储,内部存储空间有限。对于设备中每一个安装的 App,系统都会在内部存储空间的 data/data 目录下以应用包名为名字自动创建与之对应的文件夹。这个文件夹用于 App 中的 WebView 缓存页面信息,SharedPreferences 和 SQLiteDatabase 持久化应用相关数据等。
内部存储包含的文件
外部存储
在安卓文件的外部存储部分又分为了应用的私有目录和共有目录。
私有目录
外部的存储的私有目录地址可以根据context的相应方法得到。
公共目录
外部的存储的公有目录可以根据Environment的相应方法得到。
创建文件测试
通过file创建data文件
Test 1
Filefile = newFile("data");
try{
//新建文件
booleanbl=file.createNewFile();
//判断文件创建是否成功
Log.d("myTag","onCreate:"+bl);
}catch(IOExceptione){
e.printStackTrace();
}
运行结果
文件创建失败
同时文件夹中没有出现该文件
猜测创建失败问题来自文件地址的问题
Test 2
Filefile=null;
file=newFile(getCacheDir()+"data");
try{
//新建文件
booleanbl=file.createNewFile();
//判断文件创建是否成功
Log.d("myTag","onCreate:"+bl);
}catch(IOExceptione){
e.printStackTrace();
}
运行结果
文件创建成功,同时在/data/data/com.example.myapplication的地址处生成了名为cachedata的文件
文件名与预期不同
Test 3
Filefile=null;
file=newFile(getFilesDir()+"data");
try{
//新建文件
booleanbl=file.createNewFile();
//判断文件创建是否成功
Log.d("myTag","onCreate:"+bl);
}catch(IOExceptione){
e.printStackTrace();
}
运行结果
创建了一个files文件夹及一个filesdata文件
filesdata文件位置:/data/data/com.example.myapplication/filesdata
Test 4
Filefile=null;
file=newFile(getCodeCacheDir()+"data");
try{
//新建文件
booleanbl=file.createNewFile();
//判断文件创建是否成功
Log.d("myTag","onCreate:"+bl);
}catch(IOExceptione){
e.printStackTrace();
}
运行结果
code_cachedata地址:/data/data/com.example.myapplication/code_cachedata
Test 5
Filefile=null;
file=newFile(getCacheDir().getPath(),"data");
try{
//新建文件
booleanbl=file.createNewFile();
//判断文件创建是否成功
Log.d("myTag","onCreate:"+bl);
}catch(IOExceptione){
e.printStackTrace();
}
运行结果
成功在cache文件下创建data文件
总结使用file类创建文件时需要详细的地址,这里的地址可以通过context的getcacheDir()等方法得到
使用openFileinputStream创建
FileInputStreaminputStream=null;
try{
inputStream=openFileInput("data");
}catch(FileNotFoundExceptione){
e.printStackTrace();
}finally{
try{
inputStream.close();
}catch(IOExceptione){
e.printStackTrace();
}
新建了一个文件夹而没有新建文件
将输入流改为输出流后
FileOutputStreamoutputStream=null;
try{
outputStream=openFileOutput("data",MODE_PRIVATE);
}catch(FileNotFoundExceptione){
e.printStackTrace();
}finally{
try{
outputStream.close();
}catch(IOExceptione){
e.printStackTrace();
}
成功创建文件
使用openfilexxxxstream在只输入文件名进行创建文件时会默认在data/data/包名/files处创建文件,若不存在files文件则会新建一个files文件
File file = new File();
方法会读取该文件地址的文件,如果没有也不会报错。
file.createNewFile();
会向该地址创建一个文件,返回一个bool值以判断是否创建成功
openFileInputstream/openFileOutputstream都只能操作data/data/包名 处的文件
Tast 6
Filefile;
file=newFile(getExternalCacheDir(),"data");
try{
booleanbl=file.createNewFile();
Log.d("myTag","onCreate:"+bl);
}catch(IOExceptione){
e.printStackTrace();
}
需要读写公共空间操作有所区别
Filefile;
file=Environment.(Environment.DIRECTORY_DOWNLOADS);
FilemFile;
mFile=newFile(file,"data");
try{
booleanbl=mFile.createNewFile();
Log.d("myTag","onCreate:"+bl);
}catch(IOExceptione){
e.printStackTrace();
}
需要申明读写权限对于android6.0以上还需要动态申请权限
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/>
最后附上安卓所有文件存储的地址的获取方法