As把数据存储到文件

Android应用程序存储数据的方式:

1、保存到文件
2、SQLite数据库
3、内容提供者ContentProvider
4、sharedproferrences保存数据
5、网络

    /data/data/应用包名/info.txt
 

  • 从内存中读写文件(先把数据写入内存文件中,在从内存文件中读取数据并显示到界面上)

1、创建一个文件,目录data/data/<包名>/文件名(eclipse中和AS中的内存文件的存储目录一样)
2、创建一个文件输出流,把数据写到文件上
3、关闭输出流。

4、读取文件中的数据,并显示到界面上

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.ahu_lichang.myapplication.MainActivity"
    android:orientation="vertical"
    >

    <EditText
        android:id="@+id/et_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入用户名"
        />
    <EditText
        android:id="@+id/et_pass"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPassword"
        android:hint="请输入密码"
        />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <CheckBox
            android:id="@+id/cb"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="记住用户名和密码"
            android:layout_centerVertical="true"
            />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:text="登录"
            android:layout_alignParentRight="true"
            android:onClick="login"
            />
    </RelativeLayout>

</LinearLayout>

 

package com.example.ahu_lichang.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
/**
 * 在内存中读写文件中数据
 */
public class MainActivity extends AppCompatActivity {
    private EditText et_name;
    private EditText et_pass;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_name = (EditText) findViewById(R.id.et_name);
        et_pass = (EditText) findViewById(R.id.et_pass);

        readAccount();

    }

    /**
     * 从内存文件中读取数据
     */
    public void readAccount(){
        File file = new File("data/data/com.example.ahu_lichang.myapplication/info.txt");//Tools->ADM->DDMS,在里面的文件浏览里能找到
        if(file.exists()){
            try {
                FileInputStream fis = new FileInputStream(file);
                //把字节流转换成字符流
                BufferedReader br = new BufferedReader(new InputStreamReader(fis));
                //读取txt文件里的用户名和密码
                String text = br.readLine();
                String[] s = text.split("##");

                et_name.setText(s[0]);
                et_pass.setText(s[1]);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 先登录,将name和pass保存在内存中
     */
    public void login(View v){

        String name = et_name.getText().toString();
        String pass = et_pass.getText().toString();

        CheckBox cb = (CheckBox) findViewById(R.id.cb);
        //判断选框是否被勾选
        if(cb.isChecked()){
            //data/data/com.ahu.androidtest:这就是内部存储空间的路径
            File file = new File("data/data/com.example.ahu_lichang.myapplication/info.txt");
            FileOutputStream fos;
            try {
                fos = new FileOutputStream(file);
                fos.write((name + "##" + pass).getBytes());
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //创建并显示吐司对话框
        Toast.makeText(this, "登录成功", 0).show();
    }
}

 

 

 

读写SD卡中的文件(重点—Android studio实现)

    注意:SD卡路径变化:

      • sdcard:2.3之前的
      • mnt/sdcard:4.3之前的
      • storage/sdcard:4.3之后的        

 

1、必须先要创建虚拟SD卡文件镜像,然后添加到AVD中(或者用命令让指定模拟器在启动时增加虚拟SD卡镜像文件)。

1)、在Android studio使用mksdcard命令创建SD卡镜像文件:

  adb shell

  mksdcard 64M D:\sdcard.img    -----在D:\目录下创建了一个64M大小的虚拟SD卡

2)、将SD卡镜像文件添加到模拟器中:

  第一种方式:直接在创建AVD的时候,就想已有的SD卡镜像文件添加到模拟器中

  第二种方式:使用命令让指定模拟器在启动时就添加SD卡镜像文件     emulator -avd AVD5.1 -sdcard D:\sdcard.img

  2、在SD卡上先写入文件,然后在读取里面的数据显示在界面上

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.ahu_lichang.myapplication.MainActivity"
    android:orientation="vertical"
    >

    <EditText
        android:id="@+id/et_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入用户名"
        />
    <EditText
        android:id="@+id/et_pass"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPassword"
        android:hint="请输入密码"
        />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <CheckBox
            android:id="@+id/cb"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="记住用户名和密码"
            android:layout_centerVertical="true"
            />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:text="登录"
            android:layout_alignParentRight="true"
            android:onClick="login"
            />
    </RelativeLayout>

</LinearLayout>

 

package com.example.ahu_lichang.myapplication;

import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
/**
 * 在外部存储(SD卡)中读写文件中数据
 */
public class MainActivity extends AppCompatActivity {
    private EditText et_name;
    private EditText et_pass;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_name = (EditText) findViewById(R.id.et_name);
        et_pass = (EditText) findViewById(R.id.et_pass);

        readAccount();

    }

    /**
     * 从SD卡文件中读取数据
     */
    public void readAccount(){
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            File file = new File("storage/sdcard/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("##");
                    et_name.setText(s[0]);
                    et_pass.setText(s[1]);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * 先登录,将name和pass保存在SD卡中
     */
    public void login(View v){

        String name = et_name.getText().toString();
        String pass = et_pass.getText().toString();

        CheckBox cb = (CheckBox) findViewById(R.id.cb);
        //判断选框是否被勾选
        if(cb.isChecked()){
            //MEDIA_UNKNOWN:不能识别sd卡
            //MEDIA_REMOVED:没有sd卡
            //MEDIA_UNMOUNTED:sd卡存在但是没有挂载
            //MEDIA_CHECKING:sd卡正在准备
            //MEDIA_MOUNTED:sd卡已经挂载,可用
            if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判断SD卡状态是否挂载
                File file = new File(Environment.getExternalStorageDirectory(),"info.txt");//SD卡路径
                FileOutputStream fos;
                try {
                    fos = new FileOutputStream(file);
                    fos.write((name+"##"+pass).getBytes());
                    fos.close();
                    //创建并显示吐司对话框
                    Toast.makeText(this, "登录成功", 0).show();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else{
                Toast.makeText(this, "SD卡不可用!!!",0).show();
            }
        }
    }
}


 3、添加权限:(在Android studio中读写SD卡上文件要添加创建与删除文件权限、写入数据权限,不需要读权限。eclipse中则是要添加读权限、写权限

  <!--在SD卡中创建与删除文件权限-->
2     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
3     <!--向SD卡写入数据权限-->
4     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 

  • 获取SD的大小及可用空间

 

/**
     * 获取SD卡空间大小
     */
    public void readSDSpace(){
        //获取sd卡的目录对象
        File file = Environment.getExternalStorageDirectory();
        //获取sd卡的总的大小
        Long total = file.getTotalSpace();
        //获取sd卡剩余空间的大小
        Long use = file.getUsableSpace();
        //打开DDMS,可以在LogCat观察到
        Log.e("总的大小:",total.toString());
        Log.e("剩余空间:",use.toString());
        //转换数据大小的数据单位
        String totalSize = android.text.format.Formatter.formatFileSize(this,total);
        String useSize = android.text.format.Formatter.formatFileSize(this,use);
        Log.e("格式化后总的大小:",totalSize);
        Log.e("格式化后剩余空间:",useSize);
    }

 

 

 

 

 

  • 文件的权限概念

文件的4种操作模式:
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 ,只有这样其他程序才能正确访问。

 

  • SharedPreferences存储方式(重点)

     在SharedPreferences中文件读写数据:

package com.example.ahu_lichang.myapplication;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private EditText et_name;
    private EditText et_pass;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et_name = (EditText) findViewById(R.id.et_name);
        et_pass = (EditText) findViewById(R.id.et_pass);

        readAccount();
    }

    public void readAccount(){
        /**
         * 从SharedPreferences中读取数据
         */
        SharedPreferences sp = getSharedPreferences("config",MODE_PRIVATE);
        String name = sp.getString("name","");
        String pass = sp.getString("pass","");
        et_name.setText(name);
        et_pass.setText(pass);
    }

    public void login(View v){

        String name = et_name.getText().toString();
        String pass = et_pass.getText().toString();

        CheckBox cb = (CheckBox) findViewById(R.id.cb);
        //判断选框是否被勾选
        if(cb.isChecked()){
            /**
             * 向SharedPreferences中写入数据.路径在data/data/包名/share_prefs
             */
            SharedPreferences sp = getSharedPreferences("config",MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            editor.putString("name",name);//键值对形式
            editor.putString("pass",pass);
            editor.commit();
        }
        Toast.makeText(this,"登录成功",0).show();
    }
}

 

 

 

  • 使用StringBuffer拼接字符串完成短信备份
package com.ahu.lichang.androidtest;

/**
 * Created by ahu_lichang on 2017/3/18.
 */

public class Message {
    private String body;
    private String date;
    private String address;
    private String type;
    public String getBody() {
        return body;
    }
    public void setBody(String body) {
        this.body = body;
    }
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public Message(String body, String date, String address, String type) {
        super();
        this.body = body;
        this.date = date;
        this.address = address;
        this.type = type;
    }
}
package com.ahu.lichang.androidtest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    List<Message> smsList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //虚拟10条短信
        smsList = new ArrayList<Message>();
        for(int i = 0; i < 10; i++){
            Message sms = new Message("安徽大学" + i, System.currentTimeMillis() + "", "138"+i+i, "1");
            smsList.add(sms);
        }
    }
    //点击备份短信按钮
    public void backup(View v){
        //在内存中把xml备份短信的格式拼接出来
        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>");
        sb.append("<messages>");
        for (Message 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("</messages>");

        File file = new File("storage/sdcard/sms.xml");//要添加两个权限
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(sb.toString().getBytes());
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 使用序列化器生成一个xml文件,完成短信备份
    //使用XmlSerializer序列化生成器完成短信备份
            //使用xml序列化器生成xml文件
            //1.拿到序列化器对象
            XmlSerializer xs = Xml.newSerializer();
            //2.初始化
            File file = new File("sdcard/sms2.xml");
            try {
                FileOutputStream fos = new FileOutputStream(file);
                //enconding:指定用什么编码生成xml文件
                xs.setOutput(fos, "utf-8");
    
                //3.开始生成xml文件
                //enconding:指定头结点中的enconding属性的值
                xs.startDocument("utf-8", true);
    
                xs.startTag(null, "message");
    
                for (Message sms : smsList) {
                    xs.startTag(null, "sms");
    
                    xs.startTag(null, "body");
                    xs.text(sms.getBody());
                    xs.endTag(null, "body");
    
                    xs.startTag(null, "date");
                    xs.text(sms.getDate());
                    xs.endTag(null, "date");
    
                    xs.startTag(null, "type");
                    xs.text(sms.getType());
                    xs.endTag(null, "type");
    
                    xs.startTag(null, "address");
                    xs.text(sms.getAddress());
                    xs.endTag(null, "address");
    
                    xs.endTag(null, "sms");
                }
    
                xs.endTag(null, "message");
    
                //告诉序列化器,文件生成完毕
                xs.endDocument();
            } catch (Exception e) {
                e.printStackTrace();
            }

    短信备份完成后,将SD卡中的xml文件pull出来,然后用浏览器打开该文件,就能很清晰的看见如下结果:

     

    • 使用pull解析xml格式的数据 (重要-AS实现)

         注意:1、Android studio和eclipse中的资源文件的存放位置不一样

            2、Android studio中获取资源文件的方法跟eclipse中不一样

      先在main目录下新建文件夹assets,然后再将资源文件weather.xml。

    <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
    <weather>
        <city>
            <name>上海</name>
            <temp>5°</temp>
            <pm>80</pm>
        </city>
        <city>
            <name>北京</name>
            <temp>-5°</temp>
            <pm>800</pm>
        </city>
        <city>
            <name>西安</name>
            <temp>12°</temp>
            <pm>60</pm>
        </city>
    </weather>
    编写要用到的javabean,City.java
    package com.ahu.lichang.pull;
    
    /**
     * Created by ahu_lichang on 2017/3/18.
     */
    
    public class City {
        private String name;
        private String temp;
        private String pm;
        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 getPm() {
            return pm;
        }
        public void setPm(String pm) {
            this.pm = pm;
        }
        @Override
        public String toString() {
            return "City [name=" + name + ", temp=" + temp + ", pm=" + pm + "]";
        }
    }

    布局文件
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.ahu.lichang.pull.MainActivity"
        android:orientation="vertical">
    
        <Button
            android:text="pull解析"
            android:onClick="pull"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/tv_present"
            android:text="显示出Pull解析出来的天气信息"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    最后编写用XmlPullParser解析XML文件的具体代码
    package com.ahu.lichang.pull;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Xml;
    import android.view.View;
    import android.widget.TextView;
    
    import org.xmlpull.v1.XmlPullParser;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
        private List<City> cityList;
        private TextView tv_present;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            tv_present = (TextView) findViewById(R.id.tv_present);
        }
    
        public void pull(View v){
            //获取到src文件夹下的资源文件,eclipse中这样实现
            //InputStream is = getClassLoader().getResourceAsStream("weather.xml");
            InputStream is = null;
            try {
                //在AS中,要在main下新建文件夹assets,然后将资源文件放进去
                is = this.getApplicationContext().getAssets().open("weather.xml");
            } catch (IOException e) {
                e.printStackTrace();
            }
            //拿到pull解析器对象
            XmlPullParser xp = Xml.newPullParser();
            //初始化
            try {
                xp.setInput(is, "utf-8");
                //获取当前节点的事件类型,通过事件类型的判断,我们可以知道当前节点是什么节点,从而确定我们应该做什么操作
                int type = xp.getEventType();
                City city = null;
                while(type != XmlPullParser.END_DOCUMENT){
                    //根据节点的类型,要做不同的操作
                    switch (type) {
                        case XmlPullParser.START_TAG:
                            //获取当前节点的名字
                            if("weather".equals(xp.getName())){
                                //创建city集合对象,用于存放city的javabean
                                cityList = new ArrayList<City>();
                            }
                            else if("city".equals(xp.getName())){
                                //创建city的javabean对象
                                city = new City();
                            }
                            else if("name".equals(xp.getName())){
                                //获取当前节点的下一个节点的文本
                                String name = xp.nextText();
                                city.setName(name);
                            }
                            else if("temp".equals(xp.getName())){
                                //获取当前节点的下一个节点的文本
                                String temp = xp.nextText();
                                city.setTemp(temp);
                            }
                            else if("pm".equals(xp.getName())){
                                //获取当前节点的下一个节点的文本
                                String pm = xp.nextText();
                                city.setPm(pm);
                            }
                            break;
                        case XmlPullParser.END_TAG:
                            if("city".equals(xp.getName())){
                                //把city的javabean放入集合中
                                cityList.add(city);
                            }
                            break;
                    }
                    //把指针移动到下一个节点,并返回该节点的事件类型
                    type = xp.next();
                }
                is.close();
                StringBuffer sb = new StringBuffer();
                for (City c : cityList) {
                    System.out.println(c.toString());
                    sb.append(c.toString());
                    sb.append("\n");
                }
                tv_present.setText(sb.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    运行结果



     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值