- 在android读写文件
- RAM:运行内存,相当于电脑的内存
- ROM:内部存储空间,相当电脑硬盘,android手机必须有的
- SD卡:外部存储空间,相当电脑的移动硬盘,不是必须的。手机如果内置16G存储空间,是内部空间和外部空间共用一个设备,如果还支持SD卡,新增的空间将作为外部存储空间的一个子文件夹(在外部空间建立一个快捷方式指向新增的SD卡,用程序访问外部空间访问不到新增的空间)。所以说现在手机自带的空间属于外部存储,然后手机基本内部外部共享一个存储设备
- 在内部存储读写文件
所有安装至手机的应用都会在data/data目录下生成一个包名文件夹,这个文件夹就是内部存储路径。
应用只能在自己的包文件夹下写文件
写文件
if(cb.isChecked()){
//File file = new File("data/data/com.ecollab.rwinrom/info.txt");
//返回一个FILE对象,封装的路径是data/data/com.ecollab.rwinrom/files,永久存储
//File file= new File(getFilesDir(),"info.txt");
//返回一个FILE对象,封装的路径是data/data/com.ecollab.rwinrom/cache,如果内部存储空间不足,cache的文件会被自动删除
File file= new File(getCacheDir(),"info.txt");
try {
FileOutputStream fos= new FileOutputStream(file);
fos.write((name + "&&" + pass).getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//System.out.println("登录成功");
Toast t= Toast.makeText(this, "数据存储成功", 0);
t.show();
读文件
//读取文件,回写数据
//File file = new File("data/data/com.ecollab.rwinrom/info.txt");
//返回一个FILE对象,封装的路径是data/data/com.ecollab.rwinrom/files,永久存储
//File file= new File(getFilesDir(),"info.txt");
//返回一个FILE对象,封装的路径是data/data/com.ecollab.rwinrom/cache,如果内部存储空间不足,cache的文件会被自动删除
File file= new File(getCacheDir(),"info.txt");
if(file.exists())
{
try {
FileInputStream fis = new FileInputStream(file);
//把子节流转换为字符流
BufferedReader br= new BufferedReader(new InputStreamReader(fis));
//读取文件中文本
String text= br.readLine();
String s[] = text.split("&&");
EditText et_name=(EditText) findViewById(R.id.et_name);
EditText et_pass=(EditText) findViewById(R.id.et_pass);
et_name.setText(s[0]);
et_pass.setText(s[1]);
Toast.makeText(this, "数据读取成功", 0).show();
} catch (Exception e) {
e.printStackTrace();
}
}
- 在外部存储读写文件
- 外部存储路径
- 2.2~4.2:mnt/sdcard
- 4.3开始:storage/sdcard
- 2.2之前在根目录的sdcard
2. 权限
- android.permission.WRITE_EXTERNAL_STORAGE
- android.permission.READ_EXTERNAL_STORAGE
3. 写文件
if(cb.isChecked()){
//MEDIA_REMOVED: sd卡不存在
//MEDIA_UNMOUNTED:sd存在,但是没有挂载
//MEDIA_CHECKING:sd卡正在遍历
//MEDIA_MOUNTED:sd卡可用
//MEDIA_MOUNTED_READ_ONLY:sd卡可用,但是只读
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//File file = new File("cdsard/info.txt");
//返回一个FILE对象,封装了外部存储的真实路径
File file = new File(Environment.getExternalStorageDirectory(),"info.txt");
try {
FileOutputStream fos= new FileOutputStream(file);
fos.write((name + "&&" + pass).getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//System.out.println("登录成功");
Toast t= Toast.makeText(this, "数据存储成功", 0);
t.show();
}
else {
Toast.makeText(this, "sd卡不可用哦", 0).show();
}
}
4. 读文件
//读取文件,回写数据
//File file = new File("cdsard/info.txt");
//返回一个FILE对象,封装了外部存储的真实路径
File file = new File(Environment.getExternalStorageDirectory(),"info.txt");
if(file.exists())
{
try {
FileInputStream fis = new FileInputStream(file);
//把子节流转换为字符流
BufferedReader br= new BufferedReader(new InputStreamReader(fis));
//读取文件中文本
String text= br.readLine();
String s[] = text.split("&&");
EditText et_name=(EditText) findViewById(R.id.et_name);
EditText et_pass=(EditText) findViewById(R.id.et_pass);
et_name.setText(s[0]);
et_pass.setText(s[1]);
Toast.makeText(this, "数据读取成功", 0).show();
} catch (Exception e) {
e.printStackTrace();
}
}
5. preference 已经淘汰,但在android系统源码中还在,所以读系统源码会用到。有KEY、大标题、小摘要....
6. 获取SD卡空间
每个存储设备会被分为若干个区块
每个区块的大小 * 区块总数 = 存储设备的总大小
每个区块的大小 * 可用区块总数 = 存储设备的可用总大小
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize ;
long totalBlocks;
long availableBlocks;
//判断当前版本是否4.3或以上
if(Build.VERSION.SDK_INT>=18){//或者用 Build.VERSION.SDK_INT>=Build.VERSION_CODES.JELLY_BEAN_MR2
blockSize = stat.getBlockSizeLong();
totalBlocks = stat.getBlockCountLong();
availableBlocks = stat.getAvailableBlocksLong();
}
else {
blockSize = stat.getBlockSize();
totalBlocks = stat.getBlockCount();
availableBlocks = stat.getAvailableBlocks();
}
String text = formatSize(availableBlocks * blockSize);
TextView tv=(TextView) findViewById(R.id.tv);
tv.setText(text);
- 文件的访问权限(Permissions)
drwxrwxrwx
android每一个应用都是一个独立用户,可以设置用户组。
- 第一个字母
- d:表示是文件夹
- -:表示是文件
- 第一组rwx:文件拥有者(owner)的权限
- r:表示有读权限,-表示没有
- w:写权限
- x:执行execute
- 第二组rwx:与文件拥有者同一组的用户(grouper)
- 第三组rwx:其他用户(other)的权限(不用应用之间)
- 全局文件
//默认路径为data/data/包名/files
FileOutputStream fos=openFileOutput("info1.txt", MODE_PRIVATE);//MODE_PRIVATE,MODE_WORLD_READABLE,MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE
fos.write("XXXXXXX".getBytes());
- SharedPreference
- 以键值对的形式保存数据
- 适合存放零散简单的数据
- 写文件
SharedPreferences sp = getSharedPreferences("info", MODE_PRIVATE);
//获取编辑器
Editor ed= sp.edit();
ed.putString("name", name);
ed.putString("pass", pass);
//提交,生成XML文件保存
ed.commit();
4. 读文件
SharedPreferences sp = getSharedPreferences("info", MODE_PRIVATE);
String name=sp.getString("name", "");
String pass=sp.getString("pass", "");
EditText et_name=(EditText) findViewById(R.id.et_name);
EditText et_pass=(EditText) findViewById(R.id.et_pass);
et_name.setText(name);
et_pass.setText(pass);
- 写XML文件
public class Sms {
private String body;
private long date;
private int type;
private String address;
public Sms(String body, long date, int type, String address) {
super();
this.body = body;
this.date = date;
this.type = type;
this.address = address;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public long getDate() {
return date;
}
public void setDate(long date) {
this.date = date;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
-----------------------------------------------------------------------------
public class MainActivity extends Activity {
List<com.ecollab.createxml.domain.Sms> smslist;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
smslist = new ArrayList<com.ecollab.createxml.domain.Sms>();
//虚构10条短信
for(int i=0;i<10;i++){
com.ecollab.createxml.domain.Sms sms = new com.ecollab.createxml.domain.Sms("nihao" + i, System.currentTimeMillis(), 1, "138438");
smslist.add(sms);
}
}
public void click(View v){
StringBuffer sb= new StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
sb.append("<smss>");
for(com.ecollab.createxml.domain.Sms sms :smslist){
sb.append("<sms>");
sb.append("<body>");
sb.append(sms.getBody());
sb.append("</body>");
sb.append("<date>");
sb.append(sms.getDate());
sb.append("</date>");
sb.append("<type>");
sb.append(sms.getType());
sb.append("</type>");
sb.append("<address>");
sb.append(sms.getAddress());
sb.append("</address>");
sb.append("</sms>");
}
sb.append("</smss>");
File file = new File(Environment.getExternalStorageDirectory(),"sms.xml");
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(sb.toString().getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
}
--------------------------------------------
- 序列化XML文件
//获取XML序列化器
XmlSerializer xs = Xml.newSerializer();
File file = new File(Environment.getExternalStorageDirectory(),"sms2.xml");
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
//初始化,XML文件用什么编码生成
xs.setOutput(fos, "utf-8");
//生成头节点,头节点属性的值"utf-8",是否独立?不独立要其他文件支持
xs.startDocument("utf-8",true);
//生成开始标签
xs.startTag("", "smss");
for(com.ecollab.createxml.domain.Sms sms :smslist){
xs.startTag("", "sms");
xs.startTag("", "body");
xs.text(sms.getBody());
xs.endTag("", "body");
xs.startTag("", "date");
xs.text(sms.getDate() + "");
xs.endTag("", "date");
xs.startTag("", "type");
xs.text(sms.getType() + "");
xs.endTag("", "type");
xs.startTag("", "address");
xs.text(sms.getAddress());
xs.endTag("", "address");
xs.endTag("", "sms");
}
//生成结束标签
xs.endTag("", "smss");
//序列化生成结束
xs.endDocument();
} catch (Exception e) {
e.printStackTrace();
}
- XML文件解析(案例:天气预报XML)
public class City {
private String name;
private String temp;
private String pm25;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
public String getPm25() {
return pm25;
}
public void setPm25(String pm25) {
this.pm25 = pm25;
}
@Override
public String toString() {
return "City [name=" + name + ", temp=" + temp + ", pm25=" + pm25 + "]";
}
}
---------------------------------------------------------------------------------------------------
List<City> cityList;
public void click(View v){
//获取天气信息XML文件,获取SRC下的资源
InputStream is=getClassLoader().getResourceAsStream("weather.xml");
//获取xmlpull解析器
XmlPullParser xp= Xml.newPullParser();
//初始化
try {
xp.setInput(is, "utf-8");//gbk
//获取当前节点事件类型,START_DOCUMENT=0,END_DOCUMENT=1,START_TAG=2, END_TAG=3, TEXT=4, etc
int type = xp.getEventType();
City city = null;
while(type != XmlPullParser.END_DOCUMENT){
switch (type) {
case XmlPullParser.START_TAG:
if("weather".equals(xp.getName()))
{
cityList = new ArrayList<City>();
}
else if("city".equals(xp.getName())){
city = new City();
}
else if("name".equals(xp.getName())){
//获取下一个节点的文本,如:<name>西安</name>,返回西安文本
String name = xp.nextText();
city.setName(name);
}
else if("temp".equals(xp.getName())){
String temp = xp.nextText();
city.setTemp(temp);
}
else if("pm25".equals(xp.getName())){
String pm25 = xp.nextText();
city.setPm25(pm25);
}
break;
case XmlPullParser.END_TAG:
if("city".equals(xp.getName())){
cityList.add(city);
}
break;
default:
break;
}
//把指针移动到下一节点,并返回该节点的事件类型
type = xp.next();
}
} catch (Exception e) {
e.printStackTrace();
}
for(City city:cityList){
Toast.makeText(this, city.toString(), 0);
}
}