Android & Java中的文件读取方式集合

一、Android 中的文件读取

1.读取 Android Project 下的文件

Android 资源管理框架实际就是由 AssetManager 和 Resources 两个类来实现的。其中,Resources 类可以根据 ID来 查找资源,而 AssetManager 类根据文件名来查找资源。如果一个资源 ID 对应的是一个文件,那么 Resources 类是先根据 ID 来找到资源文件名称,然后再将该文件名称交给 AssetManager 类来打开对应的文件的,这个过程下图所示。

image.png

在上图中,Resources 类根据资源 ID 来查到资源名称实际上也是要通过AssetManager 类来实现的,这是因为资源 ID 与资源名称的对应关系是由打包在APK 里面的 resources.arsc 文件中的。当 Resources 类查找的资源对应的是一个文件的时候,它就会再次将资源名称交给 AssetManager,以便后者可以打开对应的文件,否则的话,上一步找到的资源名称就是最终的查找结果,详细介绍见 Android应用程序资源的查找过程分析。

Resources 类资源如图片 drawable、布局 layout、字符串 string、动画 anim等,放在 Project 根目录的 res 子目录下。读取这类的文件资源使用相应的Id就行,比如读取一个图片资源 drawable:R.drawable.xxx。非 Resources 类的资源文件读取就需要通过 AssetManager 类来读取了,这类资源放在 Project 根目录的 assets 子目录下,与 res 同级目录,它里面保存的是一些原始的文件,可以以任何方式来进行组织,文件这些仅仅是纯文本。比如想要读取Project中的一个.json文件,则需要先创建一个与res同级目录的 assets 目录,并将 config.json 放在该目录下:

image.png

然后在代码中读取 config.json 文件。

assets 读取 project 中 config.json 文件:

private void loadConfigDataByFile() {
    AssetManager am = getAssets();  //获取一个AssetManager用于读取filename为config.json的文件
    try {
        InputStream inputStream = am.open("config.json");
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = inputStream.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
        inputStream.close();
        String state = os.toString();// 把流中的数据转换成字符串,采用的编码是utf-8(模拟器默认编码)
        appPopUpConfig = new Gson().fromJson(state, AppPopUpConfig.class);
        os.close();

    } catch (IOException e) {
        e.printStackTrace();
    }
}

注意:若在Android Project中把config.json文件放在了非assets目录下,并用文件读取方式(如FileReader)去读取就会报FileNotFound错误,比如放在如下位置

image.png

2.读取本地 sdcard 中的文件

首先,最重要的一步,在 AndroidManifest.xml 添加 sdcard 权限,不然所有的都会白搭(关于 sdcard 权限设置有话说:Android 6.0 权限适配之WRITE_EXTERNAL_STORAGE):



然后代码中读取文件,假设想读取一张本地 sdcard 图片,通常会这样写:
获取本地 sdcard 图片:

private Bitmap getDiskBitmap(String pathString) {
    Bitmap bitmap = null;
    try {
        File file = new File(pathString);
        if (file.exists()) {
            bitmap = BitmapFactory.decodeFile(pathString);
        }
    } catch (Exception e) {
        Log.e("Exception: ", e.toString());
    }
    return bitmap;
}

问题来了,pathString 要怎样写?在 Android Studio 的 Android Device Mointor查看设备的文件结构,若读取 images.jpeg 图片,根据文件结构,pathString="/mnt/shell/emulated/0/DCIM/images.jpeg",但结果并没有那个美好,读取出来的 bitmap 为 null,故该方式写路径 pathString 错误。

image.png

换个正确的姿势写路径 pathString:

//方式一:调用函数获取sdcard路径
private  String mSdRootPath = Environment.getExternalStorageDirectory().getPath();  //sdcard卡的根目录
private  String mFilePath = "/DCIM/images.jpeg";
String pathString = mSdRootPath + mFilePath;

//方式二:简单粗暴直接写
String pathString ="/sdcard/DCIM/images.jpeg";

为何将 "/mnt/shell/emulated/0/DCIM/images.jpeg" 前面一串换成 /sdcard 就能正确读取图片文件了呢?从上图标注的红色箭头可以看到,sdcard 文件链接到了storage/emulated/legacy,storage/emulated/legacy 链接到了 /mnt/shell/emulated/0,所以我们以 /sdcard 作为路径起始位置,就能正确读取出images.jpeg 了。

二、Java 中的文件读取

1.读取 Java Project 下的文件

读取文件,首先需获取文件的路径,先理清以下绝对路径和相对路径。相对路径就是相对与其他文件的路径。比如有以下这么一个文件:

image.png

MyClass.java文件的绝对路径是 javaproject/src/main/java/com/example/MyClass,config.json文件的绝对路径是 javaproject/src/main/java/config.json。那么 MyClass.java 相对于 config.json 的路径就是 com/example/MyClass(也可以写成这种形式:.com/example/MyClass)。”.” 的意思是当前目录,也就是 MyClass.java 所相对的文件所在的目录,在这里就是:javaproject/src/main/java/。
比如要读取上图中的 config.json 文件,则
读取 project 中 config.json 文件:

public static String readByFileReader() {
    String fileContent = null;
    try {
        String line = null;
        StringBuilder strBuffer = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader(new FileReader("javaproject/src/main/java/com/example/config.json")); //路径要从根目录javaproject写起
        while ((line = bufferedReader.readLine()) != null) {
            strBuffer.append(line);
        }
        bufferedReader.close();
        fileContent = strBuffer.toString();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return fileContent;
}

注意第6行,config.json的路径必须写全,从项目的根目录写起,不然会报FileNotFound错误。看网上很多说在Java Project中可以用相对路径读取文件,然而在Android Studio中实验,结果并不是,路径不写全都会报错...

2.读取磁盘中的文件

读取磁盘的文件,与读取 Project 下的文件类似,只是写路径的方式有点区别。以绝对路径方式读取磁盘文件,并以盘符开始的,例如读取磁盘 C:/workspace/android/javaproject/data.txt 文件。

读取磁盘中 data.txt 文件:

public static void readFileByBytes() {
    String fileName = "C:/workspace/android/javaproject/data.txt"; //路径从磁盘符写起
    File file = new File(fileName);
    String name = file.getName();
    InputStream in = null;
    try {
        System.out.println("以字节为单位读取文件内容,一次读一个字节:");
        // 一次读一个字节
        in = new FileInputStream(file);
        int tempbyte;
        while ((tempbyte = in.read()) != -1) {
            System.out.write(tempbyte);
        }
        in.close();
    } catch (IOException e) {
        e.printStackTrace();
        return;
    }
    try {
        System.out.println("以字节为单位读取文件内容,一次读多个字节:");
        // 一次读多个字节
        byte[] tempbytes = new byte[100];
        int byteread = 0;
        in = new FileInputStream(fileName);
        // 读入多个字节到字节数组中,byteread为一次读入的字节数
        while ((byteread = in.read(tempbytes)) != -1) {
            System.out.write(tempbytes, 0, byteread);
        }
    } catch (Exception e1) {
        e1.printStackTrace();
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e1) {
            }
        }
    }
}

根据路径读取到文件后,更多关于文件流的读取详细介绍可点这里,具体用法。

3.读取 classpath 下的文件

什么是 classpath(类路径)?假设我们在 Android Studio 中有一个 Java 工程:javaproject,在工程 javaproject 下边会自动创建两个目录:src 和 build。这个build 目录(包括 web 应用中 WEB-INF 下的 classes 目录)就统称为classpath。对于类路径下的文件,可以采取以下方式:

TODO:http://blog.csdn.net/jiaobuchong/article/details/52422954(读取结果有错)

参考链接:

http://blog.csdn.net/luoshengyang/article/details/8738877
http://www.cnblogs.com/caowei/p/2013-12-03_fileread.html

你可能感兴趣的:(Android & Java中的文件读取方式集合)