位置0:d:代表是目录,-代表是文件
位置1-3:当前用户的访问权限; r:代表可读,w:代表可写; x:代表可执行
位置4-6: 当前用户所在组的权限; r:代表可读,w:代表可写; x:代表可执行
位置7-9: 其它用户的权限 r:代表可读,w:代表可写; x:代表可执行
在android系统中文件的访问是有严格的权限的,其实这也是Linux系统的文件权限:如上图
- --- --- --- :这十个横线代表每个横线都有不同的意义
1.使用文件进行数据存储
Activity
提供了
openFileOutput()
方法可以用于把数据输出到文件中,具体的实现过程与在
J2SE
环境中保存数据到文件中是一样的。
public class FileActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
...
FileOutputStream outStream = this.openFileOutput("itcast.txt", Context.MODE_PRIVATE);
outStream.write("你好
".getBytes());
outStream.close();
}
}
openFileOutput()
方法的第一参数用于指定文件名称,不能包含路径分隔符
“/”
,如果文件不存在,
Android
会自动创建它。创建的文件保存在
/data/data/<package name>/files
目录,如
:
/data/data/cn.itcast.action/files/itcast.txt
,通过点击
Eclipse
菜单
“Window”-“Show View”-“Other”
,在对话窗口中展开
android
文件夹,选择下面的
File Explorer
视图,然后在
File Explorer
视图中展开
/data/data/<package name>/files
目录就可以看到该文件。
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
用来控制其他应用是否有权限读写该文件。
MODE_WORLD_READABLE
:表示当前文件可以被其他应用读取;
MODE_WORLD_WRITEABLE
:表示当前文件可以被其他应用写入。
如果希望文件被其他应用读和写,可以传入:
openFileOutput("itcast.txt",
Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE
);
android
有一套自己的安全模型,当应用程序
(.apk)
在安装时系统就会分配给他一个
userid
,当该应用要去访问其他资源比如文件的时候,就需要
userid
匹配。默认情况下,任何应用创建的文件,
sharedpreferences
,数据库都应该是私有的(位于
/data/data/<package name>/files
),其他程序无法访问。除非在创建时指定了
Context.MODE_WORLD_READABLE
或者
Context.MODE_WORLD_WRITEABLE
,只有这样其他程序才能正确访问。
2.将数据保存在外部SD卡中
在程序中访问
SDCard
,你需要申请访问
SDCard
的权限。
在
AndroidManifest.xml
中加入访问
SDCard
的权限如下
:
<!--
在
SDCard
中创建与删除文件权限
-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!--
往
SDCard
写入数据权限
-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
要往
SDCard
存放文件,程序必须先判断手机是否装有
SDCard
,并且可以进行读写。
注意:访问
SDCard
必须在
AndroidManifest.xml
中加入访问
SDCard
的权限
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File sdCardDir = Environment.getExternalStorageDirectory();
//
获取
SDCard
目录
File saveFile = new File(sdCardDir, “itcast.txt”);
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write("你好
".getBytes());
outStream.close();
}
Environment.getExternalStorageState()
方法用于获取
SDCard
的状态,如果手机装有
SDCard
,并且可以进行读写,那么方法返回的状态等于
Environment.MEDIA_MOUNTED
。
Environment.getExternalStorageDirectory()
方法用于获取
SDCard
的目录,当然要获取
SDCard
的目录,你也可以这样写:
File sdCardDir = new File("/mnt/sdcard");
//
获取
SDCard
目录
File saveFile = new File(sdCardDir, "itcast.txt");
//
上面两句代码可以合成一句:
File saveFile = new File("/mnt/sdcard/itcast.txt");
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write("
传智播客
test".getBytes());
outStream.close
示例代码:
package fu.dao.li.load;
import
android.app.Activity;
import
android.os.Bundle;
import
android.text.TextUtils;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.widget.Button;
import
android.widget.EditText;
import
android.widget.RadioGroup;
import
android.widget.Toast;
import
fu.dao.li.file.SaveData;
import
fu.dao.li.file.SaveToSD;
public
class
MainActivity
extends
Activity
implements
OnClickListener {
private
EditText
text
;
private
RadioGroup
radios
;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.
activity_main
);
text
=(EditText) findViewById(R.id.
text
);
radios
=(RadioGroup) findViewById(R.id.
radios
);
Button button=(Button) findViewById(R.id.
click
);
button.setOnClickListener(
this
);
}
@Override
public
void
onClick(View arg0) {
String name=
text
.getText().toString().trim();
if
(TextUtils.isEmpty(name)){
Toast. makeText(
this
,
"内容不能为空"
,Toast.
LENGTH_SHORT
).show();
//return ;
}
else
{
int
id=
radios
.getCheckedRadioButtonId();
boolean
flag=
false
;
switch
(id){
//在string文件中指定的字符串名称不能为关键字
case
R.id.
rwprivate
:
//将数据保存在外部 sd卡中
flag=SaveToSD. save(
this
, name);
//将数据保存在手机内存中
//flag=SaveData.save(this,name,1);
break
;
case
R.id.
read
:
flag=SaveData. save(
this
, name, 2);
break
;
case
R.id.
write
:
flag=SaveData. save(
this
, name,3);
break
;
case
R.id.
rwpublic
:
flag=SaveData. save(
this
, name,4);
break
;
}
if
(flag){
Toast. makeText(
this
,
"保存数据成功"
,Toast.
LENGTH_SHORT
).show();
}
else
{
Toast. makeText(
this
,
"数据没有保存成功"
,Toast.
LENGTH_SHORT
).show();
}
}
}
}
package fu.dao.li.file;
import java.io.FileOutputStream;
import java.io.IOException;
import android.annotation.SuppressLint;
import android.content.Context;
public class SaveData {
@SuppressLint({ "WorldWriteableFiles", "WorldReadableFiles" })
@SuppressWarnings("deprecation")
public static boolean save(Context context,String name,int model){
FileOutputStream fos=null;
try {
//创建不同属性的文件
switch(model){
case 1:
//创建一个私有属性的文件,它只能是当前的用户才能访问
fos=context.openFileOutput("private.txt",Context.MODE_PRIVATE);
break;
case 2:
//创建一个可读属性的文件 ,当前用户可读可写,其它用户只能读不能写
fos=context.openFileOutput("read.txt",Context.MODE_WORLD_READABLE);
break;
case 3:
//创建一个可写属性的文件,当前用户可读可写,其它用户只能写还能读
fos=context.openFileOutput("write.txt",Context.MODE_WORLD_WRITEABLE);
break;
case 4:
//创建一个公共属性的文件,当前用户其它用户都可读可写
fos=context.openFileOutput("public.txt",Context.MODE_WORLD_WRITEABLE+Context.MODE_WORLD_READABLE);
break;
}
fos.write(name.getBytes());
fos.close();
return true;
} catch (IOException e) {
return false;
}
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import android.annotation.SuppressLint;
import android.content.Context;
public class SaveData {
@SuppressLint({ "WorldWriteableFiles", "WorldReadableFiles" })
@SuppressWarnings("deprecation")
public static boolean save(Context context,String name,int model){
FileOutputStream fos=null;
try {
//创建不同属性的文件
switch(model){
case 1:
//创建一个私有属性的文件,它只能是当前的用户才能访问
fos=context.openFileOutput("private.txt",Context.MODE_PRIVATE);
break;
case 2:
//创建一个可读属性的文件 ,当前用户可读可写,其它用户只能读不能写
fos=context.openFileOutput("read.txt",Context.MODE_WORLD_READABLE);
break;
case 3:
//创建一个可写属性的文件,当前用户可读可写,其它用户只能写还能读
fos=context.openFileOutput("write.txt",Context.MODE_WORLD_WRITEABLE);
break;
case 4:
//创建一个公共属性的文件,当前用户其它用户都可读可写
fos=context.openFileOutput("public.txt",Context.MODE_WORLD_WRITEABLE+Context.MODE_WORLD_READABLE);
break;
}
fos.write(name.getBytes());
fos.close();
return true;
} catch (IOException e) {
return false;
}
}
}
package
fu.dao.li.file;
import
java.io.File;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.OutputStream;
import
android.content.Context;
import
android.os.Environment;
public
class
SaveToSD {
public
static
boolean
save(Context context,String name){
OutputStream out=
null
;
try
{
// File file=new File("/sdcard/sdcard.txt");
// 获取外部SD卡的目录
String files = Environment.getExternalStorageDirectory().toString();
// 判断外部sd卡的状态是否可用
if
(Environment.
MEDIA_MOUNTED
.equals( Environment
. getExternalStorageState())) {
// 在sd 卡中创建一个文件
File file =
new
File(Environment.getExternalStorageDirectory(),
"li.txt"
);
out =
new
FileOutputStream(file);
out.write(name.getBytes());
out.close();
}
return
true
;
}
catch
(IOException e) {
return
false
;
}
}
}
示例:获取手机内存及外部存储大小
@Override
public
void
onClick(View arg0) {
//获取手机内部存储器文件(即内存)
File path = Environment. getDataDirectory();
StatFs stat =
new
StatFs(path.getPath());
/*
* 内存空间的划分原理是:首先内存划分成很多份,而每一份的大小都是固定的;当要使用内存空间时,就将这些一个固定大小的
* 空间提供给程序使用,不管程序能否完全充分的使用这些空间,内存提供的最小单位是一个这样的空间;所以 要计算总内存时
* 只要获取划分的每个空间的大小以及划分空间的个数就,然后二都相乘就是内存空间大小了
*
* */
//获取划分的内存的最小单位
long
blockSize = stat.getBlockSizeLong();
//获取根据最小单位划分的空间总个数
long
totalBlocks = stat.getBlockCountLong();
long
freeBlocks=stat.getFreeBlocksLong();
//获取可用空间的个数
long
availableBlocks = stat.getAvailableBlocksLong();
//内存总空间大小
long
totalSize = blockSize*totalBlocks;
//内存可用空间大小
long
availSize = availableBlocks*blockSize;
long
free=freeBlocks*blockSize;
String totalStr = Formatter.formatFileSize(
this
, totalSize);
String availStr = Formatter.formatFileSize(
this
, availSize);
String freeStr=Formatter.formatFileSize(
this
,free);
sd
.setText(
"总内存:"
+totalStr+
"可用内存:"
+availStr+
"\n"
+getSdBlock());
}
public
String getSdBlock(){
//获取外部存储器的文件(一般指 sd卡)
File path = Environment.getExternalStorageDirectory();
StatFs stat =
new
StatFs(path.getPath());
//获取划分空间的最小单位
long
blockSize = stat.getBlockSizeLong();
//获取根据最小单位划分的空间总个数
long
totalBlocks = stat.getBlockCountLong();
//获取可用空间的个数
long
availableBlocks = stat.getAvailableBlocksLong();
//SD总空间大小
long
totalSize = blockSize*totalBlocks;
//SD可用空间大小
long
availSize = availableBlocks*blockSize;
String totalStr = Formatter.formatFileSize(
this
, totalSize);
String availStr = Formatter.formatFileSize(
this
, availSize);
return
"sd总空间"
+totalStr+
"可用空间"
+availStr;
}
3.使用SharedPreferences进行数据存储
很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友。
对于软件配置参数的保存,如果是window软件通常我们会采用ini文件进行保存,如果是j2se应用,我们会采用properties属性文件或者xml进行保存。
如果是Android应用,Android平台给我们提供了一个SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数。
使用SharedPreferences保存数据,其背后是用xml文件存放数据,文件存放在/data/data/<package name>/shared_prefs目录下:
存储SharedPreferences中的数据:
SharedPreferences sharedPreferences = getSharedPreferences("itcast", Context.MODE_PRIVATE);Editor editor = sharedPreferences.edit();//获取编辑器editor.putString("name", "传智播客");editor.putInt("age", 4);editor.commit();//提交修改
生成的itcast.xml文件内容如下:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?><map><string name="name">传智播客</string><int name="age" value="4" /></map>
因为SharedPreferences背后是使用xml文件保存数据,getSharedPreferences(name,mode)方法的第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由Android自动加上。方法的第二个参数指定文件的操作模式,共有四种操作模式,这四种模式前面介绍使用文件方式保存数据时已经讲解过。
如果希望SharedPreferences背后使用的xml文件能被其他应用读和写,可以指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限。
另外Activity还提供了另一个getPreferences(mode)方法操作SharedPreferences,这个方法默认使用当前类不带包名的类名作为文件的名称。
访问SharedPreferences中的数据:
SharedPreferences sharedPreferences = getSharedPreferences("itcast", Context.MODE_PRIVATE);//getString()第二个参数为缺省值,如果preference中不存在该key,将返回缺省值String name = sharedPreferences.getString("name", "");int age = sharedPreferences.getInt("age", 1);
如果访问其他应用中的Preference,前提条件是:该preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限。如:有个<package name>为cn.itcast.action的应用使用下面语句创建了preference。
getSharedPreferences("itcast", Context.MODE_WORLD_READABLE);
其他应用要访问上面应用的preference,首先需要创建上面应用的Context,然后通过Context 访问preference ,访问preference时会在应用所在包下的shared_prefs目录找到preference :
Context otherAppsContext = createPackageContext("cn.itcast.action", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences = otherAppsContext.getSharedPreferences("itcast", Context.MODE_WORLD_READABLE);
String name = sharedPreferences.getString("name", "");
int age = sharedPreferences.getInt("age", 0);
如果不通过创建Context访问其他应用的preference,也可以以读取xml文件方式直接访问其他应用preference对应的xml文件,如:
File xmlFile = new File(“/data/data/<package name>/shared_prefs/itcast.xml”);//<package name>应替换成应用的包名
示例代码:
public
static
void
sharePreferences(Context context,String name,String pass){
/*
* 在window中,一般用. ini来存储配置文件,j2e中用properties类和 xml来存储配置文件
* 在android中用一个特别的接口,它提供了存储配置文件的方法
* ShsredPreferences的实现类是一个轻量级的存储类,特别适合用于存储配置文件
* */
//在内存空间的data/data/[package]的文件夹下创建一个shared- prefs的文件夹,在文件中创建一个context.xml文件
SharedPreferences share=context.getSharedPreferences(
"context"
,Context.
MODE_PRIVATE
);
//获得编辑器
Editor edit=share.edit();
//编辑数据
edit.putString(
"username"
,name);
edit.putString(
"password"
,pass);
//提交内容
edit.commit();
}
//取出文件中的数据
//如果内存中不存在指定名的文件则创建
sharepreferences
对象,否则返回这个文件(和java中的输出流类似)
SharedPreferences share=
this
.getSharedPreferences(
"context"
,Context.
MODE_PRIVATE
);
//根据键取值,其实SharePreferences内部 是用一个map来存储数据的
String textname=share.getString(
"username"
,
" "
);
//第二个参数表示,如果文件中不存在该键则默认返回这个值
String textpassword=share.getString(
"password"
,
" "
);
int
age=share.getInt(
"age"
, 1);
//如果文件中不存在word这个键则返回10086
long
ps=share.getLong(
"word"
,10086);