1.文件储存
该储存方式是比较常用的方法,分为内部存储和外部存储。在Android中读取/写入文件的方法,与java中实现I/O程序是一样的,通过I/O流的形式把数据直接存储到文档中。Android提供了openFileInput()方法与openFileOutput()方法来读取设备上的文件。可以存储大数据,如文本、图片、音频等。
2 内部存储(Internal storage)
内部存储是指将应用程序中的数据以文件方式存储到设备的内部(该文件默认位于data/data/<packagename>/files/目录下,该路径挂载再手机自身储存目录),内部存储方式储存的文件被其所创建的应用程序所私有,如果其他应用程序要操作本应用程序中的文件,需要设置权限。当创建的应用程序被卸载时,其内部存储文件也随之删除。
内部存储路径调用的方法是:
context().getCacheDir().getAbsolutePath() //通过context调用 因此很多开发中获取存储路径的方法代码如下所示:
public static String getFilePath(Context context,String dir){ String directoryPath = ""; //判断SD卡是否可用 if(MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){ direcotryPath = context.getExternalFilesDir(dir).getAbsolutePath(); //direcotryPath = context.getExternalFilesDir().getAbsolutePath(); }else{ //没内存卡就存手机机身内存中 directoryPath = context.getFilesDir() + File.separator + dir; //directoryPath = context.getCacheDir() + File.separator + dir; } File file = new File(directory); if(!file.exits()){ //判断文件目录是否已经存在 file.mkdirs(); } return directoryPath(); }
注意:getExternalCacheDir()与getCacheDir()的区别,就像getExternalFilesDir()及getFilesDir()的区别相同。前者只是在路径下自动创建好了一个cache目录:/data/<package name>/files/cche/... 内部存储存使用的是Context提供的openFileOutput()方法和openFileInput()方法,通过这两个方法可以分别获取FileOutputStream对象和FileInputStream对象,然后进行读写操作。实例代码如下:
FileOutputStream fos = openFileOutput(String name, int mode); FileInputStream fis = openFileInput(String name);
name:表示文件名
mode:表示文件的操作方式,如下:
》MODE_PRIVATE:该文件只能被当前程序读写
》MODE_APPEND:该文件的内容可以追加
》MODE_WORLD_READABLE:该文件的内容可以被其他程序读
》MODE_WORLD_WEITEABLE:该文件的内容可以被其他程序写
【注意】:默认应用程序创建的文件为私有,要想其他程序可以访问,要在文件创建时指定操作模式。
实例代码1如下:使用FileOutputStream对象将数据存储到文件中
String fileName = "data.txt"; String content = "hello world!"; FileOutputStream fos; try{ fos = openFileOutput(fileName,MODE_PRIVATE); fos.write(content.getBytes()); fos.close(); }catch(Exception e){ e.printStackTrace(); }
实例代码2如下:使用FileInputStream对象读取数据
String content = ""; FileInputStream fis; try{ fis = openFileInput("data.txt"); //创建缓冲区,并获取文件的长度 byte[] buffer = new byte[fis.available()]; //将文件内容读取到buffer缓冲区 fis.read(buffer); //转换成字符串 content = new String(buffer); fis.close(); }catch(Exception e){ e.printStackTrace(): }
3 外部存储(External storage)
3.1 外部存储概念
外部存储是指将文件储存到一些外部设备上,例如SD卡或者设备内嵌的存储卡,属于永久性的储存方式(该文件通常位于mnt/scard目录下)。Android的API6.0之后,根目录文件储存是需要用户授权的,即使再AndroidManifest.xml中配合了储存权限,也是需要用户动态授权的,如果用户不授权也无法使用。
外部存储的文件可以被其他应用程序所共享,当外部存储设备连接到计算机时,这些文件可以被浏览、修改和删除,因此这种方式是不安全的。
3.2 方法
由于外部存储设备可能被移除、丢失或者处于其他状态,因此在使用外部设备之前必须使用如下方法:
Environment.getExternalStorageState() 用于确认外部设备是否可用 Environment.getExternalStorageDirectory() 用于获取SD卡根目录 Environment.getExternalStorageDirectory().getAbsolute() 获取到绝对路径 当外部设备可用并且具有读写权限时,那么就可用通过FileInputStream、FileOutputStream对象来读写外部设备中的文件。
3.3 存储存路径
storage或者mnt文件夹 Environment.getExternalStorageDirectory() 共有目录(DICM,DOWNLOAD等) 私有目录(Android/data/应用包名,会随着应用卸载而删除) Google提供了最佳的外部存储方案,也就是统一路径为:
/android/data/<package name>/files/......(该路径通常挂载在/mnt/sdcard目录下) 外部存储存路径调用的两种方法如下:
context.getExternalFilesDir(String type).getAbsolutePath() 通过context调用,传入的参数是Environment类中的Environment.XXX静态变量,比如Environment.DIRECOTRY_MOVIES等,应用在外部存储上的目录
context.getExternalCacheDir() 获取到SDCard/Android/data/包名/cache/目录 3.4 实例代码
向外部设备(SD卡)存储数据,实例代码如下:
//获取外部设备状态 String state = Environment.getExternalStorageState(); //判断外部设备是否可用 if(state.equals(Environment.MEDIA_MOUNTED)){ String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/data.txt"; File file = new File(path); try{ if(!file.exists()){ file.createNewFile(); } String data = "Hello,World!"; FileOutputStream fos = new FileOutputStream(file); fos.write(data.getBytes()); fos.close(); }catch(Exception e){ e.printStackTrace(); } }
向外部设备(SD卡)读取数据,实例代码如下:
//获取外部设备状态 String state = Environment.getExternalStorageState(); //判断外部设备是否可用 if(state.equals(Environment.MEDIA_MOUNTED)){ //获取SD卡目录 File SDPath = Environment.getExternalStorageDirectory(); File file = new File(SDPath,"data.txt"); FileInputStream fis; try{ fis = new FileIntputStream(file); BufferedReader br = new BufferedReader(new InputStreamReader(fis)); String data = br.readLine(); fis.close(); }catch(Exception e){ e.printStackTrace(); } } -----------------------------------方式二 try { String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/data.txt"; FileInputStream inputStream = new FileInputStream(path); byte[] content = new byte[1024]; int len = inputStream.read(content); String msg = new String(content,0,len); txtText.setText(msg); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
3.5 获取权限
在写入时,需要添加如下权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" tools:ignore="ProtectedPermissions"/> 在写入时,需要添加如下权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 3.6 外部储存的动态权限(6.0以上)
ContextCompat.checkSelfPermission(Context context,Permission permission) 返回检查指定权限是否拥有的结果 ActivityCompat.requestPermission(Activity activity,String[] permission,int code) 动态配置包含指定数组里面的权限 代码如下:
//返回查询指定的权限是否拥有的结果 int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); //如果权限没有被赋予 if(permission == PackageManager.PERMISSION_DENIED){ //动态申请权限 ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1); }
3.7 外部储存私有目录
4 外部存储和内部存储区别表
区别 方法 路径与备注 外部存储 Environment.getExternalStorageDirectory() SD卡根目录:/mnt/sdcard/(6.0后写入需要用户授权) context.getExternalFilesDir(dir)
context.getExternalCacheDir()
/mnt/sdcard/Android/data/<package name>/files/...
/mnt/sdcard/Android/data/<package name>/cache/...
内部存储 context.getFilesDir()
/data/data/<package name>files.,,,
context.getCacheDir() /data/data/<package name>/cache/...
5.内存(Memory)