android 文件存储 Internal storage External storage


我们知道电脑上的文件是存储在硬盘上的,硬盘逻辑划分为C盘,D盘,E盘… 。Andrdoi设备文件存储区域被分为内部存储(internal)和外部存储区域(external),两个名称来自与早先的Android系统中,那个时候大多数的设备都内置了不可变的内存(internalstorage),
然后再加上一个类似SD card(external storage)这样可以卸载的存储部件。后来有一些设备把”internal” 与 “external” 的部分都做成不可卸载的内置存储了,虽然如此,但是这一整块还是从逻辑上被划分为”internal”与”external”的。只是现在不再以是否可以卸载来区分了。
内部存储和外部存储特点
Internal storage:
总是可用的
这里的文件默认是只能被你的app所访问的。
当用户卸载你的app的时候,系统会把internal里面的相关文件都清除干净。
Internal是在你想确保不被用户与其他app所访问的最佳存储区域。
External storage:
并不总是可用的,因为用户可以选择把这部分作为USB存储模式,这样就不可以访问了。
是大家都可以访问的,因此保存到这里的文件是失去访问控制权限的。
当用户卸载你的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
External是在你不需要严格的访问权限并且你希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。
Tip: 尽管app是默认被安装到internal storage的,你还是可以通过在程序的manifest文件中声明android:installLocation 属性来指定程序也可以被安装到external storage。当某个程序的安装文件很大,用户会倾向这个程序能够提供安装到external storage的选项。
操作外部存储时需加上权限
1
<manifest ...>
2
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
4
    ...
5
</manifest>
保存数据到内部存储
当保存文件到internal storage时,你可以通过执行下面两个方法之一来获取合适的目录作为File的对象:
getFilesDir() : 返回一个File,代表了你的app的internal目录。 /data/data/com.example.android/files/
getCacheDir() : 返回一个File,代表了你的app的internal缓存目录。 /data/data/com.example.android/cache/
为了在那些目录下创建一个新的文件,你可以使用File() 构造器,如下:
1
File file = new File(getFilesDir(), filename);
2
 
3
        FileOutputStream os;
4
        try {
5
            os = new FileOutputStream(file);
6
            os.write(string.getBytes());
7
            os.close();
8
 
9
        } catch (FileNotFoundException e) {
10
            e.printStackTrace();
11
        } catch (IOException e) {
12
            e.printStackTrace();
13
        }
同样,你也可以执行openFileOutput() 来获取一个 FileOutputStream 用来写文件到internal目录。如下:
1
String filename = "myfile";
2
String string = "Hello world!";
3
FileOutputStream outputStream;
4
 
5
try {
6
  outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
7
  outputStream.write(string.getBytes());
8
  outputStream.close();
9
} catch (Exception e) {
10
  e.printStackTrace();
11
}
保存文件到外部存储
1.外部存储进行读写时需检查是否可用
1
/**
2
     * 检查外部存储是否可用
3
     * @return
4
     */
5
    private boolean isExternalStorageWritable() {
6
        String state = Environment.getExternalStorageState();
7
        if (state.equals(Environment.MEDIA_MOUNTED)) {
8
            return true;
9
        } else {
10
            return false;
11
        }
12
    }
2.外部存储分为两个区域:公共区域(public)和私有区域(private)
公共区域 :这些文件对与用户与其他app来说是public的,当用户卸载你的app时,这些文件应该保留。例如,那些被你的app拍摄的图片或者下载的文件。
私有区域: 这些文件应该是被你的app所拥有的,它们应该在你的app被卸载时删除掉。尽管那些文件从技术上可以被用户与其他app所访问,实际上那些文件对于其他app是没有意义的。所以,当用户卸载你的app时,系统会删除你的app的private目录。例如,那些被你的app下载的缓存文件。
保存文件到公共区域,使用getExternalStoragePublicDirectory()方法来获取一个 File 对象。这个方法会需要你带有一个特定的参数来指定这些public的文件类型,以便于与其他public文件进行分类。参数类型包括DIRECTORY_MUSIC 或者 DIRECTORY_PICTURES. 如下:
1
public File getPictureStorageDir(String pictureName) {
2
 
3
    // Get the directory for the user's public pictures directory.
4
    File file = new File(Environment.getExternalStoragePublicDirectory(
5
            Environment.DIRECTORY_PICTURES), pictureName);
6
    if (!file.mkdirs()) {
7
        Log.e(LOG_TAG, "Directory not created");
8
    }
9
    return file;
10
}
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)对应的路径为:”mnt/sdcard/Pictures”
Environment.getExternalStoragePublicDirectory(参数) 参数对应目录如下:
Music/—媒体扫描器把在这个目录中找到所有媒体文件作为用户音乐。
Podcasts/—媒体扫描器把在这个目录中找到的所有媒体文件作为音/视频的剪辑片段。
Ringtones/—媒体扫描器把在这个目录中找到的所有媒体文件作为铃声。
Alarms/—媒体扫描器把在这个目录中找到的所有媒体文件作为闹钟的声音。
Pictures/—所有的图片(不包括那些用照相机拍摄的照片)。
Movies/—所有的电影(不包括那些用摄像机拍摄的视频)。
Download/—其他下载的内容。
保存文件到私有区域,执行getExternalFilesDir() 来获取相应的目录,并且传递一个指示文件类型的参数,如下示例:
1
public File getAlbumStorageDir(Context context, String albumName) {
2
    // Get the directory for the app's private pictures directory.
3
    File file = new File(context.getExternalFilesDir(
4
            Environment.DIRECTORY_PICTURES), albumName);
5
    if (!file.mkdirs()) {
6
        Log.e(LOG_TAG, "Directory not created");
7
    }
8
    return file;
9
}
context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)对应的路径为:”/mnt/sdcard/Android/data/com.example.xx/files/Pictures”
getExternalFilesDir()方法中传递null. 返回你app的外部存储私有区域根目录。
实例(从APP读取图片资源写入外部存储公共区域,接着从外部存储公共区域读到图上文件显示到界面)
1
mWriterBtn.setOnClickListener(new OnClickListener() {
2
 
3
            @Override
4
            public void onClick(View v) {
5
                if (!isExternalStorageWritable()) {
6
                    Toast.makeText(MyFileActivity.this, "外部存储不可用", Toast.LENGTH_SHORT).show();
7
                    return;
8
                }
9
 
10
                File file = new File(fileDir, PCITRUE_FILE_NAME);
11
                FileOutputStream os;
12
                try {
13
                    os = new FileOutputStream(file);
14
 
15
                    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.m3);
16
 
17
                    bitmap.compress(Bitmap.CompressFormat.PNG, 90, os);
18
 
19
                    os.close();
20
 
21
                } catch (FileNotFoundException e) {
22
                    e.printStackTrace();
23
                } catch (IOException e) {
24
                    e.printStackTrace();
25
                }
26
            }
27
        });
28
 
29
        mReaderBtn.setOnClickListener(new OnClickListener() {
30
 
31
            @Override
32
            public void onClick(View v) {
33
                if (!isExternalStorageWritable()) {
34
                    Toast.makeText(MyFileActivity.this, "外部存储不可用", Toast.LENGTH_SHORT).show();
35
                    return;
36
                }
37
 
38
                File file = new File(fileDir, PCITRUE_FILE_NAME);
39
                mDirTxt.setText(file.getPath());
40
 
41
                Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());
42
 
43
                mShowImg.setImageBitmap(bitmap);
44
            }
45
        });

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值