android的数据储存(1)(SharedPreference、File)

一、有些时候程序有少量的数据需要存储时,而且格式简单,是普通的字符串,标量等,对于这种数据android提供了SharedPreference进行保存。

二、SharedPreference保存的数据是简单的key--value对,SharedPreference接口主要负责,读取应用程序的SharedPreference数据,而SharedPreference是没有写的能力,只有读的能力。

由于SharedPreference是接口,是无法直接创建实例,只有通过Context提供的getSharedPreferences(String name,int mode)

name:为数据保存的文件名

mode:可以有三个,但是其中有两个是不安全的,android已经不再推荐了。所以mode用:MODE_PRIVATE

1、boolean  contains(String key):判断SharedPreference是否包含特定的key

2、abstract Map<String,?> getAll():获取SharedPreference中的全部key--value对3、

3、boolean getXxx(String key, xx defValue):获取SharedPreference指定的key--value,如果存在value则返回,如果不存在就返回defValue默认值。其中xx可以是boolean,flaot,int,long,String等。

三、要实现数据的写入,要使用Editor对象,此对象是通过SharedPreference调用edit()方法得到、Editor对象提供如下的方法对数据的写入。

扫描二维码关注公众号,回复: 4116075 查看本文章

1、SharedPreference.Editor  clear():清空SharedPreference里面的所有数据

2、SharedPreference.Editor  putXxx(String key,xxx  value):向SharedPreference里面存入指定key对的数据,xxx可以是boolean,flaot,int,long,String等。

3、SharedPreference.Editor  remove(String key):删除SharedPreference里面指定的key对数据项

4、boolean  commit():当Editor编辑完成后,调用该方法提交修改

实例:对SharedPreference数据进行操作

1、xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/write"
        android:text="write"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/read"
        android:text="read"/>
</LinearLayout>

2、activity

public class SharedPreferencesActivity extends AppCompatActivity {
    SharedPreferences sharedPreferences;
    SharedPreferences.Editor editor;
    static int count;
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        setContentView(R.layout.sharedpreferences_activity);

        sharedPreferences=getSharedPreferences("crazyit",MODE_PRIVATE);  
        //sharedPreferences为接口,无法直接创建,调用context中的方法,实例化sharedPreferences,进行对数据的读

        editor=sharedPreferences.edit();
      //调用方法获得Editor对象,对数据进行写

        Button write=findViewById(R.id.write);
        Button read=findViewById(R.id.read);

       count=sharedPreferences.getInt("count",0);

        write.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日"+"hh:mm:ss");
                editor.putString("time",sdf.format(new Date()));  //写入日期
                editor.putInt("random",(int)(Math.random()*100));  //写入一个整数
                editor.putInt("count",++count);        //写入count
                editor.commit();                //提交修改
            }
        });
        read.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {    //进行读
                String time=sharedPreferences.getString("time",null);  
                int random=sharedPreferences.getInt("random",0);
                int count1=sharedPreferences.getInt("count",0);
                Toast.makeText(SharedPreferencesActivity.this,time+" "+random+" "+count1,Toast.LENGTH_SHORT).show();
            }
        });
    }

}

四、File存储

一、Context提供了如下的两种方式打开程序数据文件的io流

1、FileInputStream openFileInput(String name):打开应用程序数据文件下的name文件对应输入流,对于读数据

2、FileOutputStream openFileOutput(String name,int mode):打开应用程序的数据文件下name文件对应的输入流,对应写数据,

其中mode对应三个模式,但是其中两个已经不推荐使用,所以mode:MODE_PRIVATE

二、Context还提供了如下的几种方式访问应用程序的数据文件

1、getDir(String name,int mdoe):在应用程序的数据文件夹下获取或创建name对应的子目录

2、File getFilesDir():获取应用程序的数据文件的绝对路径

3、String[]  fileList():返回应用程序文件夹下的全部文件

4、deleteFile(String):删除应用程序的数据文件指定的文件

向程序数据文件夹内输入数据:

    //以追加的方式打开文件夹的输入流
    FileOutputStream fos=openFileOutput(FILE_NAME,MODE_PRIVATE);
    //将FileOutputStream封装成printStream
    PrintStream ps=new PrintStream(fos);
   //输出内容到文件
    ps.print(content);
    ps.close();

向应用程序数据文件读数据

   //打开name程序数据文件流输入流
    FileInputStream fil=openFileInput(FILE_NAME);
    //用于接收每次读出的数据
    byte[] buff=new byte[1024];
    int hasRead=0; 
   //读取出来的全部数据
    StringBuilder builder=new StringBuilder(); 
    while((hasRead=fil.read(buff))>0){  //判断数据是否读完
        builder.append(new String(buff,0,hasRead));
    }
    //关闭文件流
    fil.close();

实例:程序写如数据到程序文件夹内,在读取文件夹里面的内容

public class FileActivity  extends AppCompatActivity{

    private String FILE_NAME="/crazyit.bin";
    EditText editText1;
    EditText editText2;
    protected void onCreate(Bundle saveInstanceSate) {
        super.onCreate(saveInstanceSate);
        LinearLayout linearLayout=new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        Button read=new Button(this);
        Button write=new Button(this);
        read.setText("read");
        write.setText("write");
        editText1=new EditText(this);
        editText2=new EditText(this);

        linearLayout.addView(write);
        linearLayout.addView(editText1);
        linearLayout.addView(read);
        linearLayout.addView(editText2);
        setContentView(linearLayout);


        read.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                editText2.setText(read());
            }
        });
        write.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                write(editText1.getText().toString());
                editText1.setText("");
            }
        });


    }

    private String read(){

        //向应用程序的数据文件夹read
        try{
            FileInputStream fil=openFileInput(FILE_NAME);
            byte[] buff=new byte[1024];
            int hasRead=0;
            StringBuilder builder=new StringBuilder();
            while((hasRead=fil.read(buff))>0){
                builder.append(new String(buff,0,hasRead));
            }
            //关闭文件流
            fil.close();
            return builder.toString();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void write(String content)
    {

        //向应用程序的数据文件夹write
        try{
            FileOutputStream fos=openFileOutput(FILE_NAME,MODE_PRIVATE);
            //将FileOutputStream封装成printStream
            PrintStream ps=new PrintStream(fos);
            ps.print(content);
            ps.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

}

五、读取SD卡上的文件

一、为了更好地存取应用程序地大文件,应用程序需要读写SD卡上的文件,SD卡大大地扩充了手机地存储功能。分为几个步骤。

1、调用Environment的getExteranlStorageState():方法判断手机是否插入SD卡,并且应用程序具有读写的SD卡的权限。

//如果手机已插入sd卡,且应用程序具有对鞋SD卡的能力,下面返回false

Environment.getExternalStorageDirectory().equals(Environment.MEDIA_MOUNTED)

2、调用Environment的getExternalStorageDirectory()方法来获取外部存储器,也就是SD卡的目录

3、使用FileInputStream,FileOutputStream   ,FileRead或者FileWrite(),方法来读写SD卡

4、读写SD卡是一个危险权限,需要在androidManifest.xml文件中声明权限

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>    //sd卡中删除文件权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>       //sd卡中读写文件权限

SD卡读:

    //如果手机插入SD卡,而且应用程序具有访问sd卡的权限
    if(!Environment.getExternalStorageDirectory().equals(Environment.MEDIA_MOUNTED)){
        //获取sd卡对应的存储目录
        File sdCardDir=Environment.getExternalStorageDirectory();
        //获取指定文件的输入流
        FileInputStream fis=new FileInputStream(sdCardDir.getCanonicalPath()+FILE_NAME);
        
        //将指定的输入流包装成BBufferedReader
        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(fis));
        StringBuilder builder=new StringBuilder("");
        String line=null;
        while ((line=bufferedReader.readLine())!=null){
            builder.append(line);
        }
        bufferedReader.close();

        return builder.toString();
    }

SD卡写:

if(!Environment.getExternalStorageDirectory().equals(Environment.MEDIA_MOUNTED)){
    //获取sd卡对应的存储目录
    Toast.makeText(FileActivity.this,"有权限",Toast.LENGTH_SHORT).show();

    File sdCardDir=Environment.getExternalStorageDirectory();
    File targetFile=new File(sdCardDir.getCanonicalPath()+FILE_NAME);
    Toast.makeText(FileActivity.this,sdCardDir.getCanonicalPath()+FILE_NAME,Toast.LENGTH_SHORT).show();

    //将指定文件创建RandomAccessFile对象
    //这里使用RandomAccessFile向SD卡中指定追加内容,如果使用FileOutputStream向指定文件写数据会将原有的文件内容清空,而不是追加的方式
    RandomAccessFile raf=new RandomAccessFile(targetFile,"rw");
    //将文件的指针移动到最后面
    raf.seek(targetFile.length());
    //输出文件内容
    raf.write(content.getBytes());
    Toast.makeText(FileActivity.this,"完成",Toast.LENGTH_SHORT).show();

    raf.close();
}

实例:读写sd卡中的数据

public class FileActivity  extends AppCompatActivity{

    private String FILE_NAME="/crazyit.bin";
    EditText editText1;
    EditText editText2;
    protected void onCreate(Bundle saveInstanceSate) {
        super.onCreate(saveInstanceSate);
        LinearLayout linearLayout=new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        Button read=new Button(this);
        Button write=new Button(this);
        read.setText("read");
        write.setText("write");
        editText1=new EditText(this);
        editText2=new EditText(this);

        linearLayout.addView(write);
        linearLayout.addView(editText1);
        linearLayout.addView(read);
        linearLayout.addView(editText2);
        setContentView(linearLayout);


        read.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                editText2.setText(read());
            }
        });
        write.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                write(editText1.getText().toString());
                editText1.setText("");
            }
        });


    }

    private String read(){

        //SD卡读
        try{
            //如果手机插入SD卡,而且应用程序具有访问sd卡的权限
            if(!Environment.getExternalStorageDirectory().equals(Environment.MEDIA_MOUNTED)){
                //获取sd卡对应的存储目录
                File sdCardDir=Environment.getExternalStorageDirectory();
                //获取指定文件的输入流
                FileInputStream fis=new FileInputStream(sdCardDir.getCanonicalPath()+FILE_NAME);

                //将指定的输入流包装成BBufferedReader
                BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(fis));
                StringBuilder builder=new StringBuilder("");
                String line=null;
                while ((line=bufferedReader.readLine())!=null){
                    builder.append(line);
                }
                bufferedReader.close();

                return builder.toString();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void write(String content)
    {

        //SD卡写
        try{
            //如果手机插入SD卡,而且应用程序具有访问sd卡的权限
            if(!Environment.getExternalStorageDirectory().equals(Environment.MEDIA_MOUNTED)){
                //获取sd卡对应的存储目录
                Toast.makeText(FileActivity.this,"有权限",Toast.LENGTH_SHORT).show();

                File sdCardDir=Environment.getExternalStorageDirectory();
                File targetFile=new File(sdCardDir.getCanonicalPath()+FILE_NAME);
                Toast.makeText(FileActivity.this,sdCardDir.getCanonicalPath()+FILE_NAME,Toast.LENGTH_SHORT).show();

                //将指定文件创建RandomAccessFile对象
                //这里使用RandomAccessFile向SD卡中指定追加内容,如果使用FileOutputStream向指定文件写数据会将原有的文件内容清空,而不是追加的方式
                RandomAccessFile raf=new RandomAccessFile(targetFile,"rw");
                //将文件的指针移动到最后面
                raf.seek(targetFile.length());
                //输出文件内容
                raf.write(content.getBytes());
                Toast.makeText(FileActivity.this,"完成",Toast.LENGTH_SHORT).show();

                raf.close();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

实例:sd卡文件夹浏览器

(如果开发者不想用Environment.getExternalStorageDirectory().equals(Environment.MEDIA_MOUNTED),也可以使用/mnt/sdcard/路径代表SD卡路径

1、xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/path"
        android:textSize="20sp"
        android:layout_gravity="center_horizontal"
        android:layout_alignParentTop="true"/>
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/list"
        android:divider="#000"
        android:dividerHeight="1px"
        android:layout_below="@+id/path"/>
    <Button
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@drawable/pzb"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:id="@+id/parent"/>
</RelativeLayout>

2、activity

public class FileListActivity extends AppCompatActivity {

    ListView listView;
    TextView textView;
    //当前父目录
    File currentParent;
    File[] currentFiles;

    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        setContentView(R.layout.listfile_activity);

        listView=findViewById(R.id.list);
        textView=findViewById(R.id.path);

        //获取系统的SD卡的目录
        File root=new File("/mnt/sdcard/");
        //如果SD卡存在
        if(root.exists()){
            currentParent=root;
            currentFiles=root.listFiles();
            //使用当前目录下面的全部文件,文件夹来填充listView
            inflateListView(currentFiles);
        }

        //为listview的列表的单击事件绑定监听器
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

                //如果用户点击文件不是,直接返回,不做任何处理
                if(currentFiles[i].isFile())
                    return ;
                //获取用户点击的文件夹下面的文件夹
                File []tmp=currentFiles[i].listFiles();
                if(tmp==null||tmp.length==0){
                    Toast.makeText(FileListActivity.this,"当前的路径不可访问,该路径下面没有文件",Toast.LENGTH_SHORT).show();
                }else {
                    //获取用户单击的列表项对应的文件夹,设当前的文件夹为父文件夹
                    currentParent=currentFiles[i];
                    //保存当前点的父文件夹的全部内容
                    currentFiles=tmp;
                    //再次更新ListView
                    inflateListView(currentFiles);
                }
            }
        });
        //获取上一级目录按钮
        Button parent=findViewById(R.id.parent);
        parent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    if(!currentParent.getCanonicalPath().equals("/mnt/sdcard")){
                        //获取上一级目录
                        currentParent=currentParent.getParentFile();
                        //列出当前目录下面的所有文件
                        currentFiles=currentParent.listFiles();
                        //再次更新listView
                        inflateListView(currentFiles);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void inflateListView(File[] files){
        //创建一个list集合,list集合的元素是Map
        List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
        for(int i=0;i<files.length;i++){
            Map<String,Object> listItem=new HashMap<String,Object>();
            //如果当前的file是文件,使用folder图标,否则使用file图标
            if(files[i].isDirectory()){
                listItem.put("icon",R.drawable.p7txxw);
            }
            else{
                listItem.put("icon",R.drawable.tp);
            }
            listItem.put("fileName",files[i].getName());
            //添加list项
            list.add(listItem);
        }

        SimpleAdapter adapter=new SimpleAdapter(this,list,R.layout.filelist_item,new String[]{"icon","fileName"},new int[]{R.id.file_image,R.id.file_name});
        listView.setAdapter(adapter);

        try{
            textView.setText("当前目录:"+currentParent.getCanonicalPath());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/wenge1477/article/details/81396021