7.使用api读取文件路径getCacheDir()、getFilesDir()、getExternalFilesDir()、getExternalCacheDir()

本文详细介绍了Android应用中数据存储的不同方式及其应用场景。包括内部存储(如cache和files目录)和外部存储(SD卡)的使用方法,特别是如何利用Context.getExternalFilesDir()和Context.getExternalCacheDir()确保应用卸载后不遗留垃圾数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

getCacheDir()方法用于获取/data/data/<application package>/cache目录

getFilesDir()方法用于获取/data/data/<application package>/files目录


应用程序在运行的过程中如果需要向手机上保存数据,一般是把数据保存在SDcard中的。
大部分应用是直接在SDCard的根目录下创建一个文件夹,然后把数据保存在该文件夹中。
这样当该应用被卸载后,这些数据还保留在SDCard中,留下了垃圾数据。
如果你想让你的应用被卸载后,与该应用相关的数据也清除掉,该怎么办呢?

通过Context.getExternalFilesDir()方法可以获取到 SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据
通过Context.getExternalCacheDir()方法可以获取到 SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据

如果使用上面的方法,当你的应用在被用户卸载后,SDCard/Android/data/你的应用的包名/ 这个目录下的所有文件都会被删除,不会留下垃圾信息。


较优秀的程序都会专门写一个方法来获取缓存地址,如下所示:

public String getDiskCacheDir(Context context) {  
    String cachePath = null;  
    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())  
            || !Environment.isExternalStorageRemovable()) {  
        cachePath = context.getExternalCacheDir().getPath();  
    } else {  
        cachePath = context.getCacheDir().getPath();  
    }  
    return cachePath;  
}

可以看到,当SD卡存在或者SD卡不可被移除的时候,就调用getExternalCacheDir()方法来获取缓存路径,否则就调用getCacheDir()方法来获取缓存路径。前者获取到的就是 /sdcard/Android/data/<application package>/cache 这个路径,而后者获取到的是 /data/data/<application package>/cache 这个路径。


数据存储:
1.内存
2.内存设备--->应用名--->(cache/files/其他名字):用的少
3.内存设备--->Android--->data--->应用名--->(cache/files/其他名字):用的多
4.sd卡--->应用名--->(files/cache/其他名字):用得少
5.sd卡--->Android--->data--->应用名--->(cache/files/其他名字):用的多

getCacheDir()用法示例

public class MainActivity extends Activity {

    private EditText et_name;
	private EditText et_pass;


	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        et_name = (EditText) findViewById(R.id.et_name);
    	et_pass = (EditText) findViewById(R.id.et_pass);
        read();
    }
    
    //读取文件
    public void read(){
    	//使用api读取路径,下面2种方法效果一样
    	 //File file = new File("data/data/com.ldw.rwinrom/12.txt");
    	 File file = new File(getFilesDir(),"123.txt");
    	 if(file.exists()){
	    	 try {
	    		 
				FileInputStream fis = new FileInputStream(file);
				//把字节流转换成字符流
				BufferedReader br = new BufferedReader(new InputStreamReader(fis));
				//读取txt里面的数据,readLine可以读取一行数据
				String text = br.readLine();
				String[] s = text.split("==");
		    	
		    	et_name.setText(s[0]);
		    	et_pass.setText(s[1]);
		    	fis.close();
		    	br.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	 
    	 }
    }

    //点击登陆写文件
    public void login(View v){
    	
    	CheckBox cb = (CheckBox) findViewById(R.id.cb);
    	String name = et_name.getText().toString();
    	String password = et_pass.getText().toString();
    	
    	if(cb.isChecked()){
    		//data/data/com.ldw.rwinrom:存储空间的路径
    		//File file = new File("data/data/com.ldw.rwinrom/12.txt");
    		File file = new File(getFilesDir(),"123.txt");
    		
    		try {
    			FileOutputStream fos = new FileOutputStream(file);
				fos.write((name + "==" + password).getBytes());
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	
    	Toast.makeText(this, "登陆成功", Toast.LENGTH_SHORT).show();
    	
    }

 

<think>嗯,用户想了解Android中的文件存储方法。首先,我需要回忆一下Android文件系统的基本结构。记得Android有内部存储和外部存储之分,可能还有分区存储的概念,特别是从Android 11开始的变化。 用户提到了参考引用里的内部存储路径是data/user/0/packageName,外部存储是storage/emulated/0/android/data/packageName。这说明需要区分应用私有目录和公共目录。可能还需要提到MediaStore和SAF(Storage Access Framework)吧? 首先,应该按存储类型分类:内部存储、外部私有存储、外部公共存储,以及分区存储的影响。然后,每种存储方式的使用方法,比如如何读写文件,需要的权限,不同Android版本的区别,比如Android 10及以上需要分区存储,可能要用MediaStore来访问公共文件。 还要注意权限问题,比如以前需要WRITE_EXTERNAL_STORAGE,但现在可能不需要了,特别是应用私有目录。可能需要给出代码示例,比如使用Context的getFilesDir(),或者Environment.getExternalStoragePublicDirectory(),不过后者可能已经被弃用了,应该用MediaStore代替。 另外,用户可能需要知道如何保存不同类型的文件,比如图片、文档等。还有,如何处理外部存储的可用性检查,比如是否挂载。还有,在AndroidManifest.xml中声明权限,以及处理Scoped Storage带来的变化。 可能还需要提到缓存目录的使用,比如getCacheDir()getExternalCacheDir(),以及何时使用它们。此外,使用FileProvider来共享文件,避免FileUriExposedException。 用户可能的问题会涉及具体代码实现,比如如何读写内部存储,如何保存到下载目录,或者如何处理权限请求。因此,在回答中需要分步骤说明,并给出示例代码,同时注意版本差异。 最后,生成的相关问题可能包括分区存储的影响、不同存储位置的优缺点、特定文件类型的保存方法等。需要确保引用正确,特别是参考内容中的路径和分区存储的变化。</think>### Android文件存储方法教程 #### 一、存储类型与路径 1. **内部存储** - 路径:$data/user/0/\text{packageName}$(应用私有目录)[^1] - 特点:无需权限,应用卸载时数据自动清除 - 代码示例: ```kotlin val file = File(context.filesDir, "example.txt") file.writeText("内部存储示例") ``` 2. **外部私有存储** - 路径:$storage/emulated/0/Android/data/\text{packageName}$ - 特点:无需权限,可存储大型文件 - 代码示例: ```kotlin val externalDir = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) val file = File(externalDir, "external_example.txt") ``` 3. **公共存储(分区存储)** - Android 11+ 需通过$MediaStore$访问公共目录(如DCIM、Downloads) - 权限要求: - Android 10+:声明$android:requestLegacyExternalStorage="true"$(仅限适配过渡期) - 部分场景需申请$READ_EXTERNAL_STORAGE$或$WRITE_EXTERNAL_STORAGE$ --- #### 二、关键API与代码实现 1. **基础文件操作** ```kotlin // 写入内部存储 context.openFileOutput("test.txt", Context.MODE_PRIVATE).use { it.write("Hello World".toByteArray()) } // 读取内部存储 context.openFileInput("test.txt").bufferedReader().use { Log.d("TAG", it.readText()) } ``` 2. **使用MediaStore保存图片** ```kotlin val values = ContentValues().apply { put(MediaStore.Images.Media.DISPLAY_NAME, "photo.jpg") put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES) } } val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values) uri?.let { contentResolver.openOutputStream(it)?.use { os -> bitmap.compress(Bitmap.CompressFormat.JPEG, 90, os) } } ``` --- #### 三、适配建议 1. **分区存储适配** - 优先使用$Context.getExternalFilesDir()$或$MediaStore$ - 访问其他应用文件时使用$Storage Access Framework$(SAF) - 示例代码: ```kotlin val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "image/*" } startActivityForResult(intent, REQUEST_CODE) ``` 2. **缓存管理** - 临时文件建议使用$context.cacheDir$或$context.externalCacheDir$ - 定期清理:`context.deleteFile(fileName)`或`file.delete()` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值