Android储存那点事

587 阅读3分钟

有一篇博客写的很好,先记下来 Android-存储基础

Android中的文件读写操作是不可或缺的,每个应用都会涉及到读写操作。这里将读写操作分成了四个部分

  1. assets文件夹中文件数据的读取
  2. raw文件夹中的文件数据的读取(目前用的很少了)
  3. Android内部存储文件的读写
  4. Android外部存储文件的读写

1. 读取assets文件夹中的数据

assets文件夹 和 res文件夹 的区别:

  1. Android系统不为assets文件夹下的文件生成ID。如果使用assets下的文件,需要指定文件的路径和文件名。存放在assets文件夹中的资源不会生成id,但是存放在res目录下的资源会生成id。
  2. assets 和 res下的文件都是只能读不能写 。
  3. Android中的资源文件主要分为两类,一种出于assets目录下,称为原生文件,这类文件在被打包成apk文件时是不会进行压缩的;另一类则是res下的文件,这类文件在打包成apk文件时,会进行小内存优化 。
  4. 虽然通过一个字符串路径来获取这个目录下的文件描述符,访问的速度会慢。但是把一些文件放在这个目录下会使一些操作更加方便,比方说拷贝一个数据库文件到系统内存中。要注意的是,你无法在Android XML文件中引用到assets目录下的文件,只能通过AssetManager来访问这些文件。数据库文件和游戏数据等放在这个目录下是比较合适的。

拷贝assets下的zip包

try {
        File file = new File("file");
        if (!file.exists()) {
            file.mkdirs();
        }
        File zipFile = new File("file" + "1.zip");
        if (!zipFile.exists()) {
            zipFile.createNewFile();
        } 
        InputStream myInput = context.getAssets().open("1.zip");
        OutputStream myOutput = new FileOutputStream("file" + "1.zip");
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        myOutput.flush();
        myOutput.close();
        myInput.close();
    } catch (IOException e) {

    } finally {
    // 需要确保在最后关闭流
        try {
            if (myOutput != null) {
                myOutput.flush();
                myOutput.close();
            }
            if (myInput != null) {
                myInput.close();
            }
        } catch (IOException e) {
            LogUtils.d(TAG, "copyAssetAndWrite finally" +
                    ", e = " + e +
                    "");
        }
    }
}

解压assets目录下的zip到指定的路径

public static void UnZipAssetsFolder(Context context, String zipFileString, String outPathString) throws Exception {
    LogUtils.d(TAG, "UnZipAssetsFolder path = " + context.getAssets().open(zipFileString).toString());
    ZipInputStream inPutZip = new ZipInputStream(context.getAssets().open(zipFileString));
    ZipEntry zipEntry;
    String szName = "";
    while ((zipEntry = inPutZip.getNextEntry()) != null) {
        szName = zipEntry.getName();
        LogUtils.d(TAG, "UnZipAssetsFolder" +
                ", szName = " + szName +
                "" +
                "");
        if (zipEntry.isDirectory()) {
            szName = szName.substring(0, szName.length() - 1);
            File folder = new File(outPathString + szName);
            //目前判断条件,如果包含解压过的文件就不再解压
            if(!folder.exists()){
                folder.mkdirs();
            }else{
                return;
            }
        } else {
            File file = new File(outPathString + szName);
            if (!file.exists()) {
                file.getParentFile().mkdirs();
                file.createNewFile();
            }

            // 获取文件的输出流
            FileOutputStream out = new FileOutputStream(file);
            int len;
            byte[] buffer = new byte[1024];

            // 读取(字节)字节到缓冲区
            while ((len = inPutZip.read(buffer)) != -1) {
            // 从缓冲区(0)位置写入(字节)字节
                out.write(buffer, 0, len);
                out.flush();
            }
            out.close();
        }
    }

    inPutZip.close();
}

2. 内部存储

内部存储在Android/data目录下,删除app后,对应目录下的文件全部删除

File rootDir = GlobalContext.INSTANCE.getGlobalContext().getExternalFilesDir("file");

LOCAL = rootDir.getAbsolutePath() + File.separator;

3. 外部存储

外部存储在其他目录下,可自定义,删除app后,文件依然存在

String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath().concat("/path")

这是存储在 Documents文件夹下

参考:# Android文件读写操作(assets 文件、 raw文件、内部存储文件、外部存储文件)

# Android 文件读写以及assets操作