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

Posted 骨灵冷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);


以上是关于Android数据存储之内部存储外部存储的主要内容,如果未能解决你的问题,请参考以下文章

Android存储及getCacheDir()getFilesDir()getExternalFilesDir()getExternalCacheDir()区别

彻底理解android中的内部存储与外部存储

Android内存解析— 详解内存,内部存储和外部存储

android内部存储与外部存储理解

如何存储卸载后剩余的数据

Android数据存储之SD卡文件操作