【问题标题】:Android how to speed up reading from a file to create Java objects using Buffered Input/Output?Android 如何加快读取文件以使用缓冲输入/输出创建 Java 对象?
【发布时间】:2014-08-20 17:36:36
【问题描述】:

我有这种方法,它从存储中获取一个 json 文件并将其转换为一堆 java 对象。如何添加缓冲输出/输入流以加快速度?还是有其他方法可以优化速度?

编辑:我不仅要使用它来读取 JSON 文件,所以我不需要 json 到 java 解析器,我实际上需要使用缓冲区来加速文件操作 :)

public static ArrayList<String> convertJSONtoArrayList(File jsonStrings) {
        FileInputStream fileInputStream = null;

        try {
            fileInputStream = new FileInputStream(jsonStrings);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }

        return convertJSONtoArrayList(fileInputStream);
    }

    public static ArrayList<String> convertJSONtoArrayList(InputStream fileInputStream) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        ArrayList<String> arrayListString = new ArrayList<String>();

        int ctr;
        try {
            if (fileInputStream != null) {
                ctr = fileInputStream.read();
                while (ctr != -1) {
                    byteArrayOutputStream.write(ctr);
                    ctr = fileInputStream.read();
                }
            }
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            // Parse the data into jsonobject to get original data in form of
            // json.
            JSONArray jsonArray = new JSONArray(byteArrayOutputStream.toString());
            int arrayLength = jsonArray.length();
            for (int i = 0; i < arrayLength; i++) {

                JSONObject jsonObject = jsonArray.getJSONObject(i);
                arrayListString.add(jsonObject.getString(Tags.VALUE));

            }

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

        return arrayListString;
    }

我的想法来自这里:How to speed up unzipping time in Java / Android? - 答案很清楚,如果添加了 BufferedInputStream,操作速度会非常好。

【问题讨论】:

  • 你检查文件读取是你的瓶颈吗?您确定需要对此进行优化吗?为什么不显示“加载”对话框?这闻起来是过早的优化。
  • 好吧,我读了 10 个文件并将它们转换为数组列表和哈希图,这些操作需要很长时间(10-20 秒),但我不确定问题出在哪里
  • 10-20 秒可能不是很多时间,具体取决于文件大小。无论如何,如果文件是独立的,请考虑对读数进行线程化。
  • 读取发生在异步任务中,您是否建议我同时为每个文件打开一个单独的线程?我怎么做?另外,缓冲不是要解决这个问题吗>?
  • 无论如何,我建议您首先找出问题所在,然后尝试找到解决方案。优化错误的部分会让你一事无成。使用 Android DDMS 检查哪些方法花费的时间最多。

标签: java android


【解决方案1】:

使用相同的代码,但将 BufferedInputStream 包裹在 FileInputStream 周围。

【讨论】:

  • 其实我的问题是如何进行包装
  • 'new BufferedInputStream(new FileInputStream(...))' 对我来说似乎很明显。
【解决方案2】:
public static List<String> convertJSONtoArrayList(File f) {
    final StringBuilder jsonString = new StringBuilder(500);
    try {
        final BufferedReader reader = new BufferedReader(new FileReader(f));
        String s;
        while ((s = reader.readLine()) != null) {
            jsonString.append(s);
        }
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
        return Collections.emptyList();
    }

    try {
        JSONArray jsonArray = new JSONArray(jsonString.toString());
        int arrayLength = jsonArray.length();
        final List<String> result = new ArrayList<String>(arrayLength);
        for (int i = 0; i < arrayLength; i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            result.add(jsonObject.getString(Tags.VALUE));
        }
        return result;
    } catch (Exception e) {
        e.printStackTrace();
        return Collections.emptyList();
    }
}

或试试这个(应该更快):

public static List<String> convertJSONtoArrayList(File f) {
    ByteBuffer buffer = ByteBuffer.allocate(f.length());
    try {
        ReadableByteChannel channel = Channels.newChannel(new FileInputStream(f));
        channel.read(buffer);
        channel.close();
    } catch (Exception e) {
        e.printStackTrace();
        return Collections.emptyList();
    }

    final String jsonString = new String(buffer.array());

    try {
        JSONArray jsonArray = new JSONArray(jsonString);
        int arrayLength = jsonArray.length();
        final List<String> result = new ArrayList<String>(arrayLength);
        for (int i = 0; i < arrayLength; i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            result.add(jsonObject.getString(Tags.VALUE));
        }
        return result;
    } catch (Exception e) {
        e.printStackTrace();
        return Collections.emptyList();
    }
}

【讨论】:

  • 实际上我需要接受 InputStream 的方法,这会改变什么吗?
  • 不,你只写 ReadableByteChannel channel = Channels.newChannel(someInputStream);
  • 但是我该怎么做:ByteBuffer.allocate(f.length());因为我没有f
  • 我尝试使用 1500 的随机值,但随后我收到一个关于字符 1500 的文件意外结束的 jsonerror
  • 不,您必须准确或更多地指定 json 文件长度的值。否则只有文件的一部分会是红色的。这就是我在 param 中创建文件对象的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多