数据存储大总结

数据存储——Android存储目录
在android系统中,应用程序持久化保存数据的方式有:(持久化保存:如果不清除会一直存在,在手机死机,重启时数据不会丢失)

存储方式:

.文件存储

·SharedPreferences
·SQLite

·网络


在android系统中,文件存储可区分为:内部存储,外部存储,缓存存储

android 系统提供了多种存储应用程序的数据的方式
开发人员应该根据以下原则进行选取:
·数据是否需要私有化
·数据的类型及其存储形式
·数据量的大小
·数据是否需要共享给其他应用程序
·其它


日志文件可以用文本文件
像应用的配置信息可能使用xml文件存储比较合适
对应数据量比较大,数据类型明确,数据之间的关联比较复杂的,需要共享给其他应用程序情况可以采用数据库存储

使用内部存储:
·当应用程序部署到设备上之后,设备上会存在路径为/data/data/应用程序  包名的文件夹,使用内部存储的方式写入的文件默认保存在该文件夹的
files  文件夹中;
·在/data/data/应用程序包名文件夹下的文件,子级文件夹是应用程序私有  的
·如果应用程序被卸载,内部存储的文件会一并移除
·在Android中,使用一般的I/O操作模式即可写实现内部存储,即使用字节流或字符流
·调用openFieInput()方法即可用获得FileInputStream对象,而调用  openFileOutput()方法则可以获得FileOutputStream对象;

在I/O相关操作中,可能需要确定读写模式,使用Context类定义的常量即可,相关的常量值有:
·MODE_PRIVATE:私有,在创建文件时即被设置为应用程序私有;写入的内容会覆盖原文件的内容,
·MODE_APPEND:添加模式
·MODE_WORLD_READABLE:全设备可读
·MODE_WORLD_WRIREABLE:全设备可写

存储目录:
存储设备:
·RAM(随机存储器,相当于电脑的内存条是cpu与其他设备交换的桥梁)
·ROM(相当于计算机的硬盘)
·SD扩展卡(相当于计算机的u盘,移动硬盘)

内部存储的相关方法
·在ContextWrapper类中定义了一系列方法,实现访问,管理内部存储相关的  文件,文件夹,常用的方法有:
·getFilesDir()访问/data/data/应用包名/files/文件夹,该方法的返回值是File类型的数据
·getDir()访问/data/data/应用包名/文件夹下指定name的文件夹,该方法的返回值是  File类型的数据
·如果需要访问的文件夹不存在,则会创建该文件夹;
·为了避免和系统可能会创建的文件夹发生冲突,开发人员自定义的文件夹会  自动被android系统加上app_前缀,但是在使用过程中开发人员可以不考虑
·fileList()
  获取私有文件列表,该方法的返回值为String[]类型数据
·deleteFile()
  删除指定的私有文件,该方法的返回值为boolean,表示是否成功删除了文件
  方法签名:public boolean deleteFile(String name);
外部存储简介
·每个兼容Android的设备都支持一个共享的外部存储空间,它可能表现为SD  卡,也可能为ROM中非应用程序私有的空间;
·一般外部存储用于保存于应用程序没有必然关系的文件,例如用户自行下载  的音乐,图片,电影等;
·外部存储的空间是设备上所有应用程序均具有读写权限的空间,不适合保存  私有数据
  sd卡是Android设备中的可选扩展存储设备,绝大部分Android设备支持用户自行扩展
挂载外部存储:
在android系统中,外不存储设备需要“挂载(mount)”之后才可以使用
在默认情况下,已正确使用的外部存储设备是“已挂载”状态;

在对外部存储设备进行写入操作时,需要添加如下权限:
 <!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  
Environment的静态方法
Environmentl类提供了一系列静态方法用于访问,管理外部存储设备,
常用的方法有:
·getExternalStorageState();
  获取外部存储的挂载状态,该方法返回String类型数据
  当SD卡未正确插入,被色定为只读,卡片破损,正在以USB形式连接PC等均会  导致其不可用,因此在使用前应该检查状态
  可使用Enviroment类的MEDIA_MOUNTED常量对比该方法的返回值
·getExternalStorageDirectory()
  获取sdcard的根目录,该方法返回值为File类型的数据;
  不同版本的设备中sdcard目录的位置可能有所不同,但是不影响该方法的使用
·getExternalStoragePublicDirectory()
  获取外部存储下指定的目录,该方法返回值为File类型数据
  该方法的参数不可为空,且应该使用Environment中的静态常量作为参数值
Environment 的静态常量
android 系统默认在外部存储下定义了Music,Pictures等文件夹,且希望开发人员有规则的使用这些文件夹,在Environment中存在以下常量表示这些
文件夹的名称:
Environment.DIRECTORY_MUSIC;音乐
Environment.DIRECTORY_RINGTONES;铃声
Environment.DIRECTORY_ALARMS;闹钟
Environment.DIRECTORY_NOTIFICATIONS;通知
Environment.DIRECTORY_PICTURES;图片
Environment.DIRECTORY_MOVIES;电影
Environment.DIRECTORY_DOWNLOADS;下载
Environment.DIRECTORY_DCIM;照相机
外部存储:
使用外部存储保存数据:
·直接使用JAVA中I/O操作即可使用外部存储保护数据
·例如在创建文件的FileInputStream,FielOutputStream对象,或FileReader,
  FileWriter对象,实现读写文件的操作,亦可使用其它流对现有的流进行包装以提高性能

关于媒体扫描:
·在Android系统中,媒体文件(图片,音乐,电影等)即使被添加到存储器  中,也不会被系统实时获取
·原生的Android系统自带应用程序可浏览图片,播放电影或音乐但并非这  些文件实时添加后,对应的应用程序即知晓文件已存在;
· Android系统使用数据库保存设备上的媒体文件信息,而各应用程序则通过  访问相关的数据库获取媒体文件的列表等信息
·在一般情况下,开机时系统会发出扫描媒体的广播,则对应的处理程序收到  该广播后将执行扫描
·开发人员可以调用

MediaScannerConnection的scanFile()静态方法


public static void scanFile (Context context, String[] paths, String[] mimeTypes, MediaScannerConnection.OnScanCompletedListener 
callback) 
数据存储-Android存储目录
04.缓存文件夹
当需要缓存一部分数据,但并非永久性保存这些数据时,即可使用缓存。
·缓存的本质依然是使用文件保存数据,区别在于:缓存的文件可能会被系统  自动清除,或开发人员应该设定某些逻辑进行清除,比如定期清除或达到限定值

内部缓存:
·调用ContextWrapper类定义的getCacheDir()方法即可获取内部缓存文件夹  ,该方法返回File类型数据
·该方法返回的File对象对应/data/data/应用程序包名/cache/文件夹;
·cache文件夹是应用程序的缓存文件夹,当设备的内部存储空间不足时
  系统会自动清理缓存文件夹以释放空间,但一般推荐开发人员自行维护缓存文件;
·当应用程序被卸载时,缓存的文件也会被清除;

外部缓存:
  调用ContextWrapper类定义的getExternalCacheDir()可获取外部缓存根目录的File的对象
·为了避免各个应用程序冲突,外部缓存文件夹路径为sdcard下的Android/data/应用程序包名/cachea/文件夹
·该方法签名
public File getExternalCachDir()

·外部缓存与内部缓存的区别:
·Android 系统并不会实时监控外部缓存的空间使用情况,因此不会自动的
 删除这些缓存文件,开发人员应该及时的手动清除不必要的文件,并把缓存文 件夹的使用空间控制在一个合理的范围内
·外部缓存并不是任何时候都可以用的
·外部存储并不具备安全性,因为任何应用程序都可以访问这些文件
最后用一个案例实践一下


(别忘了导入文件操作权限)
package com.example.file_tm;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.OnScanCompletedListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {
	protected static final int MESSAGE_SCAN_COMPLETED = 666;
	private Handler handler;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		handler = new Handler(new InnerHandlerCallback());
	}

	private class InnerHandlerCallback implements Handler.Callback{

		@Override
		public boolean handleMessage(Message msg) {
			// TODO Auto-generated method stub
			if(msg.what== MESSAGE_SCAN_COMPLETED){
				Toast.makeText(getApplicationContext(), "复制图片成功", 1).show();

			}
			return true;
		}

	}
	/*
	 * 按钮方法
	 * */
	public void copyImgFile(View v){
		File src;
		File dest;
		FileInputStream fis;
		FileOutputStream fos;
		//读取sd卡中下的一张图片进行复制
		src = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"image01.png");
		dest = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"copofimage01.png");
		try {
			fis = new FileInputStream(src);
			fos = new FileOutputStream(dest);
			byte[] buffer = new byte[1024];
			int len;
			while((len = fis.read(buffer)) != -1){
				fos.write(buffer,0,len);
			}
			fis.close();
			fos.flush();
			fos.close();
			/*
			 * 用于扫描媒体文件
			 * 这个方法是一个异步方法是在子线程中运行的
			 * 
			 * 该方法第二个参数是要扫描的路径数组,第三个参数是要扫描的文件类型,可以传入null
			 * 最后一个是扫描完成后要执行的方法,如果在给方法中Toast提示信息会报错,因为 这个方法是一个异步方法是在子线程中运行的
			 * 
			 * 如果要Toast显示提示信息可以使用android的消息机制
			 * */
			MediaScannerConnection.scanFile(this, new String[]{dest.getAbsolutePath()}, null, new OnScanCompletedListener() {

				@Override
				public void onScanCompleted(String path, Uri uri) {
					// TODO Auto-generated method stub
					handler.sendEmptyMessage(MESSAGE_SCAN_COMPLETED);
				}
			});
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

xml布局文件中加入一个按钮

 <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:onClick="copyImgFile"
        android:text="复制图片" />



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值