Android中存储目录

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wojiaohuangyu/article/details/50427792
内部存储
在Android系统中,应用程序持久化保存数据有以下的方式:
       文件存储;
       SharedPreferences;
       SQLite;
       网络。
     在Android应用程序系统中,文件存储可区分为:
         内部存储;
外部存储;
缓存存储。
如何选取数据存储的方式:
      Android系统中提供了多种存储应用程序的数据的方式,开发人员应该根据以下原则进行选取:
           数据是否需要私有化;
  数据的类型及存储形式;
  数据量的大小;
  数据是否需要共享给其他应用程序;
  等等。
使用内部存储:当应用程序部署到设备上之后,设备上会存在路径为/data/data/应用程序包名的文件夹,
使用内部存储的方式写入文件默认保存在该文件夹的files文件夹中;
在/data/data/应用程序包名 文件夹下的文件、子级文件夹是应用程序私有的;
如果应用程序被卸载,内部存储的文件会一并移除。
在Android中,使用一般的I/O操作模式即可实现内部存储,即使用字节流或字符流;
调用openFileInput()方法即可以获得FileInputStream对象,而调用openFileOutput()方法则可以获得
FileOutputStream对象;
在I/O相关操作中,可能需要确定读写模式,使用Context类定义的常量即可,相关的常量值有:
   MODE_PRIVATE:私有,在创建文件时即被设置为应用程序私有;
   MODE_APPEND:添加模式;
   MODE_WORLD_READABLE:全设备可读,即其他的应用程序也可以读该文件;
   MODE_WORLD_WRITEABLE:全设备可写,即其他的应用程序也具有对该文件的写权限。

如何将内容写入到手机内存文件中:

 简单的案例:

 package com.example.lianxi;

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

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends Activity {
   
    @Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		String str = "hello world!!";
		try {
			FileOutputStream fos= openFileOutput("sample.txt", MODE_PRIVATE);
		    byte[] buffer = str.getBytes();
		    fos.write(buffer);
		    fos.flush();
		    fos.close();
		    openFileInput("sample.txt");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

存储目录:
       Android设备中主要的存储设备有:RAM、ROM、SD扩展卡(sdcard).


       内部存储的相关的方法:在ContextWrapper类中定义了一系列方法,实现访问、管理内部存储相关的文件、文件夹,常用方法有:
          getFilesDira()
 getDir()
 deleteFile()
 fileList()
 调用getFilesDir()方法可访问/data/data/应用程序包名/files/文件夹,该方法的返回值是
 file类型的数据。
 签名:   public File getFileDir()
 getDir()方法可访问/data/data/应用程序包名/文件夹下指定name的文件夹,该方法的返回值是File类型的数据;
 如果需要访问的文件夹不存在,则会创建该文件夹;
 为避免和系统可能会创建的文件夹发生冲突,开发人员自定义的文件夹会被加上app_前缀,
 但在使用过程中,开发人员可不考虑该前缀;方法签名:
      public File getDir(String name,int mode)
 deleteFile()方法可删除指定的私有文件,该方法的返回值为boolean类型数据,表示是否成功的删除了文件;
 该方法的签名:
       public boolean deleteFile(String name)
           fileList()方法可获取私有文件列表,该方法的返回值为String[]类型数据;
          该方法签名:
      public String[] fileList()
  每个兼容Android的设备都支持一个共享的外部存储空间,它可能表现为SD卡,也可能为ROM
  中非应用程序私有的空间;
  一般外部存储用于保存与应用程序没有必然关系的文件,例如用户自行下载的音乐、图片、电影等。
  外部存储的空间是设备上所有应用程序均具有读写权限的空间,不适合保存私有数据。
  SD卡是Android设备中的可选扩展存储设备,绝大部分Android设备支持用户自行扩展。
  在Android系统中,外部存储设备需"挂载(mount)"之后才可以使用,在默认情况下,
  已正确使用的外部存储设备是“已挂载”状态;
  在对外部存储设备进行写入操作时,需要添加如下权限:
      <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  Enviroment的静态方法: Enviroment类提供了一系列静态方法用于访问、管理外部存储设备,常用的方法:
         getExternalStorageState()
 getExternalStorageDirectory()
 getExternalStoragePublicDirectory()
         调用getExternalStorageState()方法可获取外部存储的挂载状态,该方法返回String类型数据;
当SD卡未正确插入、被设为只读、卡片破损、正在以USB形式连接PC等均会导致其不可用,因此在使用前
应该检查状态;
可使用Enviroment类的MEDIA_MOUNTED常量对比该方法的返回值;
方法签名:
       public static String getExternalStorageState()
          调用 getExternalStorageDirectory()方法可获取sdcard的根目录,该方法的返回值为File类型数据;
 不同版本的设备中,sdcard目录的位置可能有所不同,但不影响该方法的使用。
  方法签名:
             public static File getExternalStorageDirextory()
        调用getExternalStoragePublicDirectory(String)方法可获取外部存储下指定的目录,该方法返回值为File类型数据;
该方法的参数不可为空,且应使用Enviroment中的静态常量作为参数值;
方法签名:
    public static File getExternalStoragePublicDirectory(String type)
 Android系统默认在外部存储下定义了Music、Picture等文件夹,且希望开发人员有规则的使用这些文件夹,在Enviroment
 中存在如下常量(String类型)表示这些文件夹的名称:
        DIRECTORY_MUSIC
DIRECTORY_RINGTONES
DIRECTORY_ALARMS
DIRECTORY_NOTIFICATIONS
DIRECTORY_PICTURES
DIRECTORY_MOVIES
DIRECTORY_DOWNLOADS
DIRECTORY_DCIM
     外部存储:
           使用外部存储保存数据
     直接使用JAVA中I/O操作即可使用外部存储来保存数据。
     一个简单的实现存储内照片复制功能,以下功能实现之后但是在虚拟机中不会马上显示出来
     ,从DDMS中文件夹下可以看到结果:
            一个按钮:

  <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="79dp"
        android:onClick="copyPicture"
        android:text="复制图片" />

 MainActivity:

 package com.example.lianxi;

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

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends Activity {
   
    @Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
    }
    
    public void copyPicture(View view){
    	File src;
    	File dest;
    	FileInputStream fis;
    	FileOutputStream fos;
    	
        try {
        	src = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"df.jpg");
        	dest = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"copy_of_df.jpg");
			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();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
}

 在安卓系统中,媒体文件(图片、音乐、电影等)即使被添加到存储器中,也不会被系统实时获取。
         原生的Android系统自带应用程序可浏览图片、播放音乐或电影,但并非这些文件实时添加后,对应的
应用程序即知晓文件已存在。
     Android系统使用数据库保存设备上的媒体文件信息,而各应用程序则通过访问相关的数据库获取媒体
     文件的列表等信息。
     在一般情况下,开机时系统会发出扫描媒体的广播,则对应的处理程序收到该广播后将执行扫描。
     开发人员可以调用MediaScannerConnection的scanFile()方法执行扫描,是媒体扫描器知晓新的媒体
     文件已经被添加到系统中。
     方法签名:
            public static void scanFile(Context context,String[] paths,String[] mimeTypes,OnscanCompletedListener callback)


       以下方法完善了上边的复制图片,能够通过通知媒体进行扫描来使得虚拟机中的图片浏览器中出现复制后的效果:
       方法如下,布局不需要改变:

 package com.example.lianxi;

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

import android.app.Activity;
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.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
   private Handler handler;
   protected static final int MESSAGE_SCAN_COMPLETED = 888;
    @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(), "复制图片成功", Toast.LENGTH_LONG).show();
			}
			return false;
		}
    	
    }
    public void copyPicture(View view){
    	File src;
    	File dest;
    	FileInputStream fis;
    	FileOutputStream fos;
    	
        try {
        	src = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"df.jpg");
        	dest = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"copy_of_df1.jpg");
			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();
			
			MediaScannerConnection.scanFile(this,new String[] {dest.getAbsolutePath()}, null, new OnScanCompletedListener() {
				
				@Override
				public void onScanCompleted(String path, Uri uri) {
					handler.sendEmptyMessage(MESSAGE_SCAN_COMPLETED);//如果在此处使用Toast会报错
				}
			});
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
}

 缓存文件夹:
           当需要缓存一部分数据,但是并不是永久性的保存这些数据时,即可使用缓存。
  缓存的本质依然是使用文件保存数据,区别在于:缓存的文件可能会被
  系统自动清除,或开发人员应该设定某些逻辑进行清除。
内部缓存:
      调用ContextWrapper类定义的getCacheDir()方法即可获取内部缓存文件夹,
      该方法返回File类型数据。
      该方法返回的File对象对应/data/data/应用程序包名/cache/文件夹;
      cache文件夹是应用程序的缓存文件夹,当设备的内部存储空间不足时,系统会自动
      清理缓存文件夹已释放空间,但一般推荐开发人员自行维护缓存文件;
      当应用程序被卸载时,缓存的文件也会被清除。
      该方法的签名:
              public File getCacheDir()
调用ContextWrapper类定义的getExternalCacheDir()可获取外部缓存
根目录的File对象;
为避免各应用程序冲突,外部缓存文件夹路径为sdcard下的Android/data/应用程序包名/cache/文件夹;
该方法的签名:
    public File getExternalCacheDir()
 外部缓存与内部缓存的区别:
     Android系统并不会实时监控外部缓存的空间使用情况,因此不会自动的
     删除这些缓存文件,开发人员应该及时的手动清理不必要的文件,并把缓存文件夹的使用空间控制在一个合理的使用范围之内;
     外部缓存并不是任何时候都可用的;
     外部缓存并不具备安全性,因为任何应用程序都可以访问这些文件。
             

阅读更多
换一批

没有更多推荐了,返回首页