Android数据存储之内部存储、外部存储

首先来介绍下什么是内部存储

在Android平台下,有着自己独立的数据存储规则,在windows平台下,应用程序可以自由的或者在特定的访问权限基础上访问或修改其他应用程序下的文件资源。

但是在Android平台下,一个应用程序所有的数据都是对外私有的,只有应用程序自己本身才可以访问。

当应用程序被安装到系统中后,其所在的包会有一个文件夹用于存放自己的数据,只有这个应用程序才有对这个文件夹的写入权限,这个私有的数据文件位于Android/data/data目录下。

读取内部数据可以使用openFileOutput方法和openFileInput()方法,前者主要是向内部数据文件写入数据,后者主要是从内部数据文件里读取数据。

具体例子如下:

首先是写入数据:

		try {
			//从内部数据里获取目标文件
			FileOutputStream fileoutput = openFileOutput("内部数据文件名", Context.MODE_PRIVATE);
			try {
				//包装秤outputstreamwriter类,方便写入
				OutputStreamWriter osw = new OutputStreamWriter(fileoutput, "制定字符集");
				try {
					//写入数据
					osw.write(new String("asdfasfs"));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

接下来是读取数据

		try {
			//从内部数据里获取目标文件
			FileInputStream fileinput = openFileInput("filename");
			//进行包装,方便读取
			InputStreamReader isr;
			try {
				isr = new InputStreamReader(fileinput, "字符集");
				//建立字符数组,用来保存读取的内容
				try {
					isr.read(new char[512]);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} catch (UnsupportedEncodingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		

以上是内部数据的读取,如果是图片等数据应当另行编码。

有了内部数据,对外部数据有该如何读取呢?

首先读取外部数据需要在Manifest文件中建立权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
获取权限之后可以操作外部存储,就是我们的SD卡

获取SD卡需要用到环境类Environment。

//获取外部存储的文件位置
File sdcard = Environment.getExternalStorageDirectory();

需要说明的是最好在获取sd卡文件目录之前先检测sd卡的状态,根据API文档说明,SD卡的状态常量表示了SD卡的当前状态,如不可读取,不存在等,具体可以参见API文档。获取SD卡的状态如下:

Environment.getExternalStorageState()

它返回的是一个String对象,因此我们可以通过equal方法与SD卡状态常量进行比较后执行后续操作。

SD卡的读取操作如下:

		//读取数据的消息响应
		btnRead.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
					File sdcardfile = new File(Environment.getExternalStorageDirectory(),"myNewFile.txt");
					//先判断sd卡文件是否存在
					if (sdcardfile.exists()) {
						//检测是否可以读取
						if (sdcardfile.canRead()) {
							try {
								FileInputStream input = new FileInputStream(sdcardfile);
								byte[] buffer = new byte[512];
								try {
									input.read(buffer);
									tv_show.setText(new String(buffer,"GB2312"));
								} catch (IOException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
								
								
							} catch (FileNotFoundException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}
					else
					{
						Toast.makeText(getApplicationContext(), "未检测到sd卡", Toast.LENGTH_SHORT).show();
						return;
					}
				}
			}
			
		});

写入SD卡:

	//写入数据的消息响应
		btnWrite.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				//获取外部存储的文件位置
				File sdcard = Environment.getExternalStorageDirectory();
				//新建文件
				File newfile = new File(sdcard, "myNewFile.txt");
				if (!sdcard.exists()) {
					Toast.makeText(getApplicationContext(), "当前sd卡路径不存在", Toast.LENGTH_SHORT).show();
					return;
				}
				else
				{
					try {
						//在我的手机的存储文件夹中创建
						if (newfile.exists()) {
							Toast.makeText(getApplicationContext(), "文件已经存在", Toast.LENGTH_SHORT).show();
							newfile.delete();
							return;
						}
						newfile.createNewFile();
						Toast.makeText(getApplicationContext(), "创建完成", Toast.LENGTH_SHORT).show();
						FileOutputStream outputstream = new FileOutputStream(newfile);
						OutputStreamWriter writer = new OutputStreamWriter(outputstream, "GB2312");
						writer.write(ed_text.getText().toString());
						writer.flush();
						writer.close();
						outputstream.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});

最后简单介绍下是如何获取sd卡的当前存储状态的:

使用的类是StatFs类,可以从文件对象的getPath()获取:

//获取sd卡的存储状态
File sdcard = Environment.getExternalStorageDirectory();
StatFs sfs = new StatFs(sdcard.getPath());
//获取总体容量
long total = sfs.getTotalBytes();
//获取当前容量
long free = sfs.getFreeBytes();	
TextView tv_sd = (TextView)findViewById(R.id.tv_sd_storage);
tv_sd.setText("SD还剩余:"+free/1024/1024+"MB /"+total/1024/1024+"MB");
ProgressBar progress = (ProgressBar) findViewById(R.id.progress);
float num = ((float)(free/1024/1024)/(float)(total/1024/1024))*100;
int progress1 = (int)num;
progress.setProgress(progress1);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值