Android中的文件IO与Preferences

在软件开发中很多情况都需要用到数据的存储,Android中存数据和取数据与Java是相似的,都需要使用流的机制。可以将数据存储到手机内存、SD卡和网络端。

Android中较为常用的是java.io.FileOutputStream和java.io.FileInputStream这一对流类,同样也需要通过File类来构造一个具体指向文件或文件夹以便操作的对象,不同的是Android中不通过新建流的类来指定文件,而是通过openFileOutput()方法和openFileInput()方法来获取流,不需要指定文件存储的位置,但需要指定文件名,文件被存储在应用程序私有的存储数据目录中/data/data/包名/files/文件名,只有该程序有写入权限。

其中输出流需要为它设置打开模式,主要有以下模式

MODE_PRIVATE:该文件只能被当前程序读写(通常选择该项)

MODE_APPEND:以追加的方式打开该文件

MODE_WORLD_READABLE:该文件的内容可以被其他程序读取

MODE_WORLD_WRITEABLE:该文件的被人可由其他程序读写。

MODE_MULTI_PROCESS:设置多线程安全

(此外Context提供了如下几个方法来访问应用程序的数据文件夹

getDir(String name,int mode):获取或创建name对应的子目录

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

String[] fileList():返回该应用程序的数据文件夹的全部文件

deleteFile(String):删除该应用程序的数据文件夹下的指定文件)

在读写文件到SD卡时需要进行SD卡是否可用判断,代码为

boolean b=Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);

存入SD卡的位置亦是固定的,获取路径方法为

Environment.getExternalStorageDirectory()

想要对SD卡进行操作需要获取两项权限:

MOUNT_UNMOUNT_FILESYSTEMS:创建和删除文件权限

WRITE_EXTERNAL_STORAGE:写入数据权限

以上方法都是将存储内容以文本文件存在手机里,Android还有一种轻量级的存储方式,以xml文件的方式存储数据,Preferences是一种轻量级的数据存储机制,它将一些简单数据类型的数据,如boolean、int、float、long、String等以键值对的形式存储在应用程序私有Preferences目录中:data/data/包名/shared_prefs

由于Preferences的使用方便和数据简单,我们一般使用Preferences存储一些配置信息,如开关状态、音量等等,其安全性也无需考虑,被看到也无所谓。

Preferences的使用要通过SharedPreferences接口实现,该接口由Context. getSharedPreferences()方法获取,其中有两个参数:文件名,如果文件不存在将自动创建,打开模式。SharePreferences接口本身没有提供写入数据的能力,而是通过SharedPreferences

的内部接口Editor,获取方法为Editor editor =sharedPreferences.edit(),它有如下方法:

       clear():清空所有数据

              putXxx(Stringkey,Xxx value):存入指定key对应的数据(Xxx指数据类型如int等)

              remove(Stringkey):删除指定key对应的数据项

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

从中读取的方法为

sharedPreferences.getString("con",null);第一个参数为key值,第二个参数为默认值,如果文件不存在或者key值不存在将返回默认值。同理还有getInt()、getBoolean()等。

以下对读写手机内存、SD卡和Preferences做一个简单测试,布局文件如下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    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.briup.file.MainActivity" >

    <EditText
        android:id="@+id/file_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Plase input File name" />

    <EditText
        android:id="@+id/file_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Plase input File content" />

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="save"
        android:text="SAVE" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="read"
        android:text="READ" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="savesd"
        android:text="SAVESD" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="readsd"
        android:text="READSD" />

    <ToggleButton
        android:id="@+id/tb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textOff="关"
        android:textOn="开" />

</LinearLayout>

MainActivity类文件如下

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

public class MainActivity extends Activity {
	private EditText fileName, fileContent;
	private TextView text;
	private ToggleButton tb;
	private String name;
	private String content;
	private boolean flag = false;

	private SharedPreferences sharedPreferences;//操作Preferences文件的类

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		fileName = (EditText) findViewById(R.id.file_name);
		fileContent = (EditText) findViewById(R.id.file_content);
		text = (TextView) findViewById(R.id.text);
		tb = (ToggleButton) findViewById(R.id.tb);
		//获得SharedPreferences对象,(文件名,打开模式)
		sharedPreferences = getSharedPreferences("isOff", Context.MODE_PRIVATE);
		//通过key值获取值,第二个参数为默认值,如果文件不存在或者没有该key值将提供该值
		tb.setChecked(sharedPreferences.getBoolean("isOff", false));
		//点击开关按钮后改变开关状态并保存该状态
		tb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
				//需要借助Editor类
				Editor editor = sharedPreferences.edit();
				editor.putBoolean("isOff", isChecked);
				editor.commit();
			}
		});
	}

	public boolean get() {
		name = fileName.getText().toString();
		content = fileContent.getText().toString();
		if (name.equals(""))
			flag = true;
		return flag;
	}

	public void save(View v) {
		//获取文本输入框内容并判空,在创建的文件时,不能没有文件名
		if (get()) {
			Toast.makeText(this, "FileName is null!",
					Toast.LENGTH_SHORT).show();
		} else {
			FileOutputStream output = null;
			try {
				// 保存至手机内存位置"data/data/com.briup.file/files",应用卸载后该文件删除
				output = openFileOutput(name, Context.MODE_PRIVATE);// Android自带的文件读写方法(文件名,文件访问格式),将文件保存在本应用程序文件夹下
				output.write(content.getBytes("UTF-8"));// 设定编码类型,Linux默认编码为UTF-8
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					output.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			Toast.makeText(MainActivity.this, "Saved success!",
					Toast.LENGTH_SHORT).show();
		}
	}

	public void read(View v) {
		if (get()) {
			Toast.makeText(this, "FileName is null!",
					Toast.LENGTH_SHORT).show();
		} else {
			FileInputStream input = null;
			BufferedReader reader = null;
			StringBuffer buffer = new StringBuffer();// StringBuffer追加字符方便
			try {
				input = openFileInput(name);// 读取本应用程序下的文件(文件名)
				reader = new BufferedReader(new InputStreamReader(input));
				String msg = "";
				while ((msg = reader.readLine()) != null) {
					buffer.append(msg);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					reader.close();
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			text.setText(buffer);
		}
	}

	public void savesd(View v) {
		if (get()) {
			Toast.makeText(this, "FileName is null!",
					Toast.LENGTH_SHORT).show();
		} else {
			// 判断SD卡是否可用,手机中不一定有SD卡
			if (Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) {
				FileOutputStream fos = null;
				String path = Environment.getExternalStorageDirectory()
						.getAbsolutePath();// 获取SD卡绝对路径
				try {
					fos = new FileOutputStream(path + "/" + name);
					fos.write(content.getBytes("UTF-8"));
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					try {
						fos.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				Toast.makeText(MainActivity.this, "Saved success!",
						Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(MainActivity.this, "SD card is disable",
						Toast.LENGTH_SHORT).show();
			}
		}
	}

	public void readsd(View v) {
		if (get()) {
			Toast.makeText(this, "FileName is null!",
					Toast.LENGTH_SHORT).show();
		} else {
			if (Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) {
				FileInputStream fis = null;
				BufferedReader reader = null;
				StringBuffer buffer = new StringBuffer();
				String path = Environment.getExternalStorageDirectory()
						.getAbsolutePath();
				try {
					fis = new FileInputStream(path + "/" + name);
					reader = new BufferedReader(new InputStreamReader(fis));
					String msg = "";
					while ((msg = reader.readLine()) != null) {
						buffer.append(msg);
					}
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					try {
						reader.close();
						fis.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				text.setText(buffer);
			} else {
				Toast.makeText(MainActivity.this, "SD card is disable",
						Toast.LENGTH_SHORT).show();
			}
		}
	}
}

配置文件如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.briup.file"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="24" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Holo.Light.NoActionBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

效果如下

 

我们对手机内存和SD分别做写和读:

 

改变开关状态,退出返回发现初始加载即是改变过的状态

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值