android 学习随笔二(读写文件)

时间:2021-04-14 06:38:14
  • 在android读写文件
  1. RAM:运行内存,相当于电脑的内存
  2. ROM:内部存储空间,相当电脑硬盘,android手机必须有的
  3. 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();
}
}

  • 在外部存储读写文件
  1. 外部存储路径
    • 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每一个应用都是一个独立用户,可以设置用户组。

    • 第一个字母
    1. d:表示是文件夹
    2. -:表示是文件
    • 第一组rwx:文件拥有者(owner)的权限
    1. r:表示有读权限,-表示没有
    2. w:写权限
    3. 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
    1. 以键值对的形式保存数据
    2. 适合存放零散简单的数据
    3. 写文件

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);
}
}